Silverlight 在LongListSelector ItemTemplate中引用数据绑定上下文菜单-Windows Phone
我正在为WindowsPhone7.5应用程序编写Silverlight 我想引用LongListSelector中的ContextMenu,因为我想在调用ContextMenuSilverlight 在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,其中包含一个名
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));
}
}
}