ContextMenu中的WPF数据绑定:直接与资源

时间:2016-03-14 15:22:16

标签: wpf mvvm data-binding

我试着用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的工作方式上有所不同。在左侧,它实现并用作资源,在右侧,它直接实现

但是为什么上下文菜单项的命令绑定只在左侧而不在右侧?

感谢您的解释: - )

1 个答案:

答案 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

找到解释