我的 ListView 上有一个上下文菜单,其中 FilterBy 作为其中的菜单项之一。此菜单项绑定(bind)到一个可观察的 Menuitems 集合(_childFilterMenuitems 来自一个对象 ContextMenuclass)。我想从 FilterBy MenuItem 的子菜单中检索所选项目并绑定(bind)到我的 MainView 模型中名为 SelectedItem 的属性。
使用中继命令和填充项目一切正常。但是我无法访问我的主视图模型中的选定项目。我尝试将 SelectedItem 属性(来自 MainViewModel)绑定(bind)到 Menuitem 上的 Tag 属性。我不能让这个工作。我阅读了几个关于可视化树及其数据上下文和放置目标的博客。标签,我不知道在哪里包含标签属性。请指导我,以便我可以建立适当的绑定(bind)。我是新手,这个网站帮了我很大的忙。
在我的 MainWindow.xaml
<ListView.ContextMenu >
<ContextMenu Name="menuListContext" >
<MenuItem Header="Reset" Name="menuReset" Command="{Binding ResetCmd}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}" >
<MenuItem Header="Filter By" ItemsSource="{Binding ChildFilterMenuItems}">
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}" <Setter Property="Header" Value="{Binding Header, Mode=TwoWay}" />
<Setter Property="ItemsSource" Value="{Binding Path= ChildFilterMenuItems}"/>
<Setter Property= "Command" Value= "{Binding DataContext.FilterByCmd, RelativeSource ={RelativeSource AncestorType={x:Type MenuItem}}}"/>
<Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=DataContext}" />
<Setter Property="Tag" Value= "{Binding DataContext.SelectedItem, RelativeSource ={RelativeSource AncestorType=MenuItem}}"/>
</Style>
</MenuItem.ItemContainerStyle>
</ContextMenu >
</ListView.ContextMenu>
MainViewModel.xaml
public class MainViewModel : ViewModelBase, INotifyPropertyChanged
{
/// <summary>
/// The menu item selected from FilterBy Menu.
/// </summary>
public string SelectedItem {get;set;}
public ObservableCollection<ContextMenuClass> ChildFilterMenuItems
{
get
{
return _childFilterMenuItems;
}
set
{
_childFilterMenuItems = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("ChildFilterMenuItems");
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{ _childFilterMenuItems = new ObservableCollection<ContextMenuClass>();
//populates the menuitems for FilterBy
PopulateFilterBy
FilterByCmd = new RelayCommand(() => FilterByMenu(), () => true);
}
private void FilterByMenu()
{
try
{
string MenuName = GetExactName(SelectedItem);
}
上下文菜单类.cs
public class ContextMenuClass : INotifyPropertyChanged
{
#region Fields
private ObservableCollection<ContextMenuClass> _filterItems;
private string _header;
private bool _isEnabled;
#endregion
#region Properties
/// <summary>
/// Gets or sets the header.
/// </summary>
/// <value>The header.</value>
public string Header
{
get
{
return _header;
}
set
{
_header = value; OnPropertyChanged("Header");
}
}
public bool IsEnabled
{
get
{
return _isEnabled;
}
set
{
_isEnabled = value; OnPropertyChanged("IsEnabled");
}
}
public ObservableCollection<ContextMenuClass> ChildFilterMenuItems
{
get
{
return (_filterItems = _filterItems ??
new ObservableCollection<ContextMenuClass>());
}
}
/// <summary>
/// Gets or sets the SelectedItem.
/// </summary>
/// <value>The header.</value>
public object SelectedMenuItem
{
get
{
return _currentItem = Header;
}
set
{
_currentItem = value; OnPropertyChanged("SelectedMenuItem");
}
}
#endregion
#region INotifyPropertyChanged
/// <summary>
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
private object _currentItem;
/// <summary>
/// Safely raises the PropertyChanged event.
/// </summary>
/// <param name="property">The property name.</param>
protected void OnPropertyChanged(string Property)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(Property));
}
}
#endregion
最佳答案
如果你想知道ContextMenuClass
对应于被点击的菜单项,你应该修改你的CommandParameter
setter 如下:
<Setter Property="CommandParameter"
Value="{Binding}" />
然后更改您的
FilterByCmd
来自 RelayCommand
到 RelayCommand<ContextMenuClass>
:FilterByCmd = new RelayCommand<ContextMenuClass>(FilterByMenu, _ => true);
并添加
ContextMenuClass
参数到您的FilterByMenu
方法:private void FilterByMenu(ContextMenuClass selectedItem)
{
// ...
}
关于wpf - 从上下文菜单的菜单项中检索所选项目。我正在使用 WPF、MVVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26982258/