我试着用WPF和MVVM踏上近一年的时间,但每当我想到我理解它是如何工作的,或者至少它是如何工作的时候,有些东西来了这不起作用,我无法理解或弄清楚原因。也许你可以帮我解决这个问题。
为了简单起见,我有一个非常基本的ViewModel:
Public Class MainViewModel
Private _testCommand As ICommand = New RelayCommand(AddressOf Me.Test)
Private _items As IEnumerable(Of String) = New String() {"Item 1", "Item 2", "Item 3"}
Public ReadOnly Property TestCommand As ICommand
Get
Return _testCommand
End Get
End Property
Private Sub Test()
MsgBox("Test")
End Sub
Public ReadOnly Property Items As IEnumerable(Of String)
Get
Return _items
End Get
End Property
End Class
这个视图模型我用作同样基本窗口的DataContext,有两个ListView
s。
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ContextMenuTest"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Window.Resources>
<ContextMenu x:Key="ItemContextMenu">
<MenuItem Header="Test Left" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, Path=DataContext.TestCommand}" />
</ContextMenu>
<Style x:Key="TestItemStyle_Left" TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
</Style>
<Style x:Key="TestItemStyle_Right" TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Test Right" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, Path=DataContext.TestCommand}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" ItemsSource="{Binding Items}" ItemContainerStyle="{StaticResource TestItemStyle_Left}">
<ListView.View>
<GridView>
<GridViewColumn Header="Test" Width="100" DisplayMemberBinding="{Binding}" />
</GridView>
</ListView.View>
</ListView>
<ListView Grid.Column="1" ItemsSource="{Binding Items}" ItemContainerStyle="{StaticResource TestItemStyle_Right}">
<ListView.View>
<GridView>
<GridViewColumn Header="Test" Width="100" DisplayMemberBinding="{Binding}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
两个ListView
都相同,只是它们使用的ItemContainerStyle
不同。
ItemContainerStyle
只在ContextMenu
的工作方式上有所不同。在左侧,它实现并用作资源,在右侧,它直接实现
但是为什么上下文菜单项的命令绑定只在左侧而不在右侧?
感谢您的解释: - )
答案 0 :(得分:-1)
如果你看一下输出窗口中的Binding Error,你会发现这个。
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ListView', AncestorLevel='1''. BindingExpression:Path=DataContext.TestCommand; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Command' (type 'ICommand')
您可以从here
找到解释