Silverlight 在LongListSelector ItemTemplate中引用数据绑定上下文菜单-Windows Phone

Silverlight 在LongListSelector ItemTemplate中引用数据绑定上下文菜单-Windows Phone,silverlight,windows-phone-7,contextmenu,silverlight-toolkit,longlistselector,Silverlight,Windows Phone 7,Contextmenu,Silverlight Toolkit,Longlistselector,我正在为WindowsPhone7.5应用程序编写Silverlight 我想引用LongListSelector中的ContextMenu,因为我想在调用ContextMenuClick事件时将.IsOpen设置为false。我的想法是,这应该自动发生,但事实并非如此 我的一个菜单项将的可见性从折叠的设置为可见的,模拟弹出窗口。虽然代码执行良好,但可见性确实发生了变化。除非ContextMenu关闭,否则应用程序的UI不会显示网格 我的LongListSelector的XAML,其中包含一个名

我正在为WindowsPhone7.5应用程序编写Silverlight

我想引用LongListSelector中的ContextMenu,因为我想在调用ContextMenu
Click
事件时将
.IsOpen
设置为
false
。我的想法是,这应该自动发生,但事实并非如此

我的一个菜单项将
的可见性从
折叠的
设置为
可见的
,模拟弹出窗口。虽然代码执行良好,但可见性确实发生了变化。除非ContextMenu关闭,否则应用程序的UI不会显示网格

我的
LongListSelector
的XAML,其中包含一个名为
Menu
ContextMenu
,我希望在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>
我在
ContextMenu\u Opened
事件中设置ContextMenu的ItemSource。这两个字段的类型均为
List


不确定为什么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;
}
然后是一个视图模型

<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>
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));
        }
    }
}
公共类ContextMenuViewModel:INotifyPropertyChanged
{
私有bool_isOpen=真;
公共上下文菜单视图模型(IEnumerable items)
{
项目=项目;
}
公共事件属性更改事件处理程序属性更改;
公共图书馆
{
获取{return _isOpen;}
设置{u isOpen=value;OnPropertyChanged(“isOpen”);}
}
公共IEnumerable项{get;set;}
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
var handler=PropertyChanged;
if(处理程序!=null)
{
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
}
}

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

ContextMenu未关闭的原因是无法在ContextMenu.ItemTemplate中设置MenuItems。如果您这样做,您将破坏ContextMenu,导致这种奇怪的行为。谢谢你的评论!感谢您提供了获取父对象的解决方案,以及关于支持ViewModel的建议。如上所述,我发现ContextMenu未关闭的原因是因为我无法在ContextMenu.ItemTemplate中指定MenuItems。但是,您的信息非常有用。:)
var menu = GetParentOfType<ContextMenu>(sender as MenuItem);
menu.IsOpen = false;
<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));
        }
    }
}