我正在使用mvvm模式,我很难搞清楚如何在ListView的ItemContainerStyle中设置ContextMenu上的DataContext。
我也不明白为什么ListView.ContextMenu和ListView的GridView.ColumnHeaderContextMenu可以从我的视图模型中看到属性和命令,但ListView.ItemContainerStyle中的ContextMenu不能。
错误
System.Windows.Data错误:40:BindingExpression路径错误:'对象'''货币'(HashCode = 43406546)'上找不到'AddMenuItem'属性。 BindingExpression:路径= AddMenuItem; DataItem ='Currency'(HashCode = 43406546); target元素是'ContextMenu'(Name =''); target属性是'ItemsSource'(类型'IEnumerable')
查看
<!-- Removed styles for clarity. -->
<UserControl>
<!-- Add ElementSpy to the UserControl’s rsources -->
<UserControl.Resources>
<framework:ElementSpy x:Key="spy" />
</UserControl.Resources>
<ListView ItemsSource="{Binding Currency}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="ContextMenu">
<Setter.Value>
<!-- 'AddMenuItem' property not found on 'object' 'Currency' -->
<!-- ContextMenu ItemsSource="{Binding AddMenuItem}" / -->
<!-- Use the ElementSpy resource -->
<ContextMenu ItemsSource="{Binding Source={StaticResource spy}, Path=Element.DataContext.AddMenuItem}" />
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ContextMenu>
<!-- Works -->
<ContextMenu ItemsSource="{Binding EditMenuItem}" />
</ListView.ContextMenu>
<ListView.View>
<GridView>
<GridView.ColumnHeaderContextMenu>
<!-- Works -->
<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>
代码背后
[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;
}
}
}
视图模型
[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;
}
// Other methods removed for clarity
}
答案 0 :(得分:2)
我更新了有此问题的其他人的来源。
为了快速参考,这就是我所做的。
添加Josh Smith的ElementSpy类。 Enable ElementName Bindings with ElementSpy
将ElementSpy添加到UserControl的rsources。
<UserControl.Resources>
<framework:ElementSpy x:Key="spy" />
</UserControl.Resources>
然后绑定到资源并使用Element属性绑定到DataContext和您选择的属性。
<ContextMenu ItemsSource="{Binding Source={StaticResource spy}, Path=Element.DataContext.AddMenuItem}" />
答案 1 :(得分:0)
您必须在绑定中使用RelativeSource和PlacementTarget。我使用以下xaml添加contextmenu来设置datagrid列的可见性。
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Spalten ein-/ausblenden">
<StackPanel>
<ItemsControl
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.Columns, Mode=OneWay}"
ItemTemplate="{StaticResource Visibility4DataGridColumns}"
></ItemsControl>
</StackPanel>
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>