I am using the mvvm template and it is difficult for me to determine how to set the DataContext in ContextMenu from inside the ListViews ItemContainerStyle.
I also donβt understand why ListView.ContextMenu and ListViews GridView.ColumnHeaderContextMenu can see properties and commands from my view model, but ContextMenu inside ListView.ItemContainerStyle cannot.
Error
System.Windows.Data error: 40: BindingExpression path error: AddMenuItem property not found in 'object' '' Currency '(HashCode = 43406546)'. BindingExpression: Path = AddMenuItem; DataItem = 'Currency' (HashCode = 43406546); target element is "ContextMenu" (Name = ''); target is "ItemsSource" (type "IEnumerable")
View
<UserControl> <UserControl.Resources> <framework:ElementSpy x:Key="spy" /> </UserControl.Resources> <ListView ItemsSource="{Binding Currency}"> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu ItemsSource="{Binding Source={StaticResource spy}, Path=Element.DataContext.AddMenuItem}" /> </Setter.Value> </Setter> </Style> </ListView.ItemContainerStyle> <ListView.ContextMenu> <ContextMenu ItemsSource="{Binding EditMenuItem}" /> </ListView.ContextMenu> <ListView.View> <GridView> <GridView.ColumnHeaderContextMenu> <ContextMenu ItemsSource="{Binding SortMenuItem}" /> </GridView.ColumnHeaderContextMenu> <GridViewColumn Header="Code" DisplayMemberBinding="{Binding Path=Code}" /> <GridViewColumn Header="Description" DisplayMemberBinding="{Binding Path=Description}" /> <GridViewColumn Header="Exchange Rate" DisplayMemberBinding="{Binding Path=ExchangeRate}" /> </GridView> </ListView.View> </ListView> </UserControl>
Code for
[Export(ViewNames.CurrencyMasterView, typeof(IMasterView))] [PartCreationPolicy(CreationPolicy.Shared)] public partial class CurrencyMasterView : UserControl, IMasterView { public CurrencyMasterView() { InitializeComponent(); } [Import] private MasterViewModel ViewModel { set { this.DataContext = value; } } }
ViewModel
[Export(typeof(MasterViewModel))] [PartCreationPolicy(CreationPolicy.NonShared)] public class MasterViewModel : ViewModelBase { [ImportingConstructor] public MasterViewModel(IGeneralController generalController, IRegionManager regionManager) { } public ObservableCollection<Currency> Currency { get { return this.currency; } set { if (this.currency != value) { this.currency = value; this.RaisePropertyChanged(() => this.Currency); } } } public List<MenuItemMvvm> SortMenuItem { get { return this.CreateSortMenuItem(); } } public List<MenuItemMvvm> EditMenuItem { get { return this.CreateEditMenuItem(); } } public List<MenuItemMvvm> AddMenuItem { get { return this.CreateAddMenuItem(); } } private List<MenuItemMvvm> CreateEditMenuItem() { var menu = new List<MenuItemMvvm>(); menu.Add(new MenuItemMvvm("_Edit") { Command = this.EditCommand, Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/POS.Modules.Core;component/Resources/Images/16X16/Edit.png")) } }); menu.Add(new MenuItemMvvm("_Duplicate") { Command = this.DuplicateCommand, Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/POS.Modules.Core;component/Resources/Images/16X16/Copy.png")) } }); menu.Add(new MenuItemMvvm("_Delete") { Command = this.DeleteCommand, Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/POS.Modules.Core;component/Resources/Images/16X16/Delete.png")) } }); return menu; }
source share