我正在为 Windows Phone 7.5 应用程序编写 Silverlight。

我想引用 LongListSelector 中的 ContextMenu 因为我想设置 .IsOpenfalse 一旦上下文菜单 Click 事件被调用。我的想法是这应该自动发生,但事实并非如此。

我的 MenuItem 之一设置了 a 的可见性 <Grid>collapsedvisible 它模仿了一个弹出窗口。虽然代码执行良好并且可见性确实发生了变化。除非 ContextMenu 关闭,否则应用程序的 UI 不会显示网格。

我的 XAML LongListSelector 其中包含一个 ContextMenu 被称为 Menu 我希望在 ContextMenuItem Click 事件中引用。

 <toolkit:LongListSelector x:Name="moviesLongList" Background="Transparent" IsFlatList="False" GroupHeaderTemplate="{StaticResource GroupHeaderTemplate}" GroupItemTemplate="{StaticResource GroupItemTemplate}" SelectionChanged="moviesLongList_SelectionChanged" GroupViewClosing="moviesLongList_GroupViewClosing" GroupViewOpened="moviesLongList_GroupViewOpened">

                    <toolkit:LongListSelector.GroupItemsPanel>
                        <ItemsPanelTemplate>
                            <toolkit:WrapPanel/>
                        </ItemsPanelTemplate>
                    </toolkit:LongListSelector.GroupItemsPanel>

                    <toolkit:LongListSelector.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Height="91" Margin="20,0,0,20" Orientation="Horizontal">
                                <toolkit:ContextMenuService.ContextMenu >
                                    <toolkit:ContextMenu x:Name="Menu" Opened="ContextMenu_Opened" Loaded="Menu_Loaded" Unloaded="Menu_Unloaded">
                                        <toolkit:ContextMenu.ItemTemplate>
                                            <DataTemplate>
                                                 <toolkit:MenuItem Header="{Binding}" Click="ContextMenuButton_Click" LostFocus="MenuItem_LostFocus" />
                                            </DataTemplate>
                                        </toolkit:ContextMenu.ItemTemplate>
                                    </toolkit:ContextMenu>
                                </toolkit:ContextMenuService.ContextMenu>

                                <Border HorizontalAlignment="Left" Width="61" Height="91" Background="{Binding ID, Converter={StaticResource ThumbImageConvert}}" />
                                <StackPanel Orientation="Vertical" HorizontalAlignment="Left" Width="395">
                                    <TextBlock x:Name="titleTextBox" Text="{Binding Title, Converter={StaticResource TitleConvert}}" Margin="6,0,6,0" d:LayoutOverrides="Width" FontSize="{StaticResource PhoneFontSizeLarge}" VerticalAlignment="Top" HorizontalAlignment="Left"/>
                                    <TextBlock x:Name="yearTextBox" Text="{Binding Year}" Margin="12,0,0,0" HorizontalAlignment="Left" FontSize="{StaticResource PhoneFontSizeMedium}" Foreground="{StaticResource PhoneSubtleBrush}" />
                                </StackPanel>
                            </StackPanel>
                        </DataTemplate>
                    </toolkit:LongListSelector.ItemTemplate>

                </toolkit:LongListSelector>

我在 ContextMenuItem Click 事件后面的代码

  private void ContextMenuButton_Click(object sender, RoutedEventArgs e)
  {
        //
        // This is where I want to set Menu.IsOpen = false to close the ContextMenu.
        //

        if ((sender as MenuItem).Header.ToString() == "lend movie")
        {
                DisableAppBarIcons();
                LendPopUpOverlay.Visibility = System.Windows.Visibility.Visible;

        }

        if ((sender as MenuItem).Header.ToString() == "return to collection")
        {
            ... Do stuff
        }

        if ((sender as MenuItem).Header.ToString() == "add to boxset")
        {
             ... Do stuff

        }

        if ((sender as MenuItem).Header.ToString() == "delete")
        {
            ... Do stuff
        }

   }

我在中设置了 ContextMenu 的 ItemSource ContextMenu_Opened 事件。这两个字段的类型都是 List<String>.

private void ContextMenu_Opened(object sender, RoutedEventArgs e)
    {
        LentMovieObj = (sender as ContextMenu).DataContext as Movies;

        if (LentMovieObj.IsLent)
        {
            (sender as ContextMenu).ItemsSource = menuItemsReturn;
        }
        else
        {
            (sender as ContextMenu).ItemsSource = menuItemsLendOut;
        }
    }
有帮助吗?

解决方案

不确定为什么 ContextMenu 没有关闭,但这里有两个解决方案。第一个是获取 MenuItem 的父级。

private T GetParentOfType<T>(DependencyObject obj) where T : class
{
    if (obj == null) return null;

    var parent = VisualTreeHelper.GetParent(obj);
    while (parent != null)
    {
        if (parent is T) return parent as T;

        parent = VisualTreeHelper.GetParent(parent);
    }

    return null;
}

然后从您的点击处理程序获取菜单

var menu = GetParentOfType<ContextMenu>(sender as MenuItem);
menu.IsOpen = false;

第二种解决方案是将 IsOpen 绑定到支持视图模型

<toolkit:ContextMenuService.ContextMenu >
    <toolkit:ContextMenu x:Name="Menu" Opened="ContextMenu_Opened" Loaded="Menu_Loaded" Unloaded="Menu_Unloaded" IsOpen="{Binding IsOpen}" ItemsSource="{Binding Items}">
        <toolkit:ContextMenu.ItemTemplate>
            <DataTemplate>
                <toolkit:MenuItem Header="{Binding}" Click="ContextMenuButton_Click" LostFocus="MenuItem_LostFocus" />
             </DataTemplate>
        </toolkit:ContextMenu.ItemTemplate>
     </toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>

更改您的开放事件:

private void ContextMenu_Opened(object sender, RoutedEventArgs e)
{
    LentMovieObj = (sender as ContextMenu).DataContext as Movies;

    if (LentMovieObj.IsLent)
    {
        (sender as ContextMenu).DataContext = new ContextMenuViewModel(menuItemsReturn);
    }
    else
    {
        (sender as ContextMenu).DataContext = ContextMenuViewModel(menuItemsLendOut);
    }
}

然后是视图模型

public class ContextMenuViewModel : INotifyPropertyChanged
{
    private bool _isOpen = true;

    public ContextMenuViewModel(IEnumerable<string> items)
    {
        Items = items;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public bool IsOpen
    {
        get { return _isOpen; }
        set { _isOpen = value; OnPropertyChanged("IsOpen"); }
    }

    public IEnumerable<String> Items { get; set; }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

然后将 ViewModel 的 IsOpen 属性设置为 false;

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top