基于所选行的WPF上下文菜单控制 [英] WPF context menu controling based on a line selected
问题描述
你好,
我有一个WPF应用程序,它显示项目列表(列表视图).
上下文菜单作为资源添加到列表视图:
Hello,
I have a WPF application which displays list of items (listview).
The context menu is added as a resource to the listview:
<listview.resources>
<contextmenu x:key="ItemContextMenu" opened="listViewContextMenu_Opened" contextmenuopening="listViewContextMenu_ContextMenuOpening" name="listViewContextMenu" xmlns:x="#unknown">
<menuitem header="Rename" previewmousedown="RenameMenuItem_MouseDown" />
<menuitem header="Delete" previewmousedown="DeleteMenuItem_MouseDown" />
<menuitem header="View File" previewmousedown="ViewFileMenuItem_PreviewMouseDown" />
</contextmenu>
</listview.resources>
然后用于项目容器样式:
And then used in an item container style:
<listview.itemcontainerstyle>
<Style TargetType="{x:Type ListViewItem}">
<eventsetter event="PreviewMouseLeftButtonDown" handler="OnListViewItem_PreviewMouseButtonDown" />
<setter property="ContextMenu" value="{StaticResource ItemContextMenu}" />
</Style>
</listview.itemcontainerstyle>
现在,问题是我想根据所选的行阻止某些上下文菜单项,即我需要分析所选的项,然后决定要显示的项.
我找不到解决方法,请帮忙!
Now, the problem is I want to prevent some context menu items based on the line selected, i.e, I need to analize the item selected and then decide which items to display.
I couldn''t find a way to do that, please help!
推荐答案
这可以通过绑定来完成.请使用以下内容:
C#-ViewModels:
Hi,
this could be accomplished with binding. Use the following:
C# - ViewModels:
public class ListViewViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public List<ItemViewModel> ItemsSource
{
get;
set;
}
public ListViewViewModel()
{
this.ItemsSource = new List<ItemViewModel>();
this.ItemsSource.Add(new ItemViewModel
{
DisplayText = "ItemsSource #1"
});
this.ItemsSource.Add(new ItemViewModel
{
DisplayText = "ItemsSource #2"
});
this.ItemsSource.Add(new ItemViewModel
{
DisplayText = "ItemsSource #3"
});
}
}
public class ItemViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string DisplayText { get; set; }
public Visibility M1Visibility {
get {
return (!this.DisplayText.Contains("1")) ? Visibility.Visible : Visibility.Collapsed;
}
}
public Visibility M2Visibility {
get {
return (!this.DisplayText.Contains("2")) ? Visibility.Visible : Visibility.Collapsed;
}
}
}
XAML:
XAML:
<ListView
ItemsSource="{Binding Path=ItemsSource}" DisplayMemberPath="DisplayText">
<ListView.ItemContainerStyle>
<Style
TargetType="{x:Type ListViewItem}">
<Setter
Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem
Header="MenueItem #1"
Visibility="{Binding Path=M1Visibility}" />
<MenuItem
Header="MenueItem #2"
Visibility="{Binding Path=M2Visibility}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
为了清楚起见,我对您的XAML进行了一些更改(至少这是我的意图).缺少一行代码,其中ListView容器的DataContext设置为ListViewViewModel的实例.
如果使用此功能,您将看到ListItem#1隐藏MenueItem#1,ListItem#2隐藏MenueItem#2,最后一个ListItem不隐藏MenueItem.
关键概念是ContextMenue的DataContext继承自ListViewItem.因此,这就是应用可见性逻辑的关键所在.您可以像我一样使用一些特定于上下文的逻辑,也可以使用初始化程序提供可见性值.
如果您需要进一步的帮助,请随时询问.
干杯
于尔根
-
如果这样可以节省您一些时间,请花点时间进行投票.
I''ve made a few changes to your XAML for the sake clearness (this was at least my intention). There is a line of code missing, where the DataContext of the ListView''s container is set to an instance of ListViewViewModel.
If you use this, you will see, that the ListItem #1 hides MenueItem #1, ListItem #2 hides MenueItem #2 and the last ListItem hides no MenueItem.
The key concept is, that the DataContext for the ContextMenue is inherited from the ListViewItem; so it is the point where to apply the visbility-logic. You can use some context-specific logic as I did or you can use the initialisers to provide the visibility values.
If you need further help, feel free to ask.
Cheers
Jürgen
--
If this saved you some time, please spend a bit of it to vote.
这篇关于基于所选行的WPF上下文菜单控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!