MVVM 如何将命令绑定到 ContextMenu
MVVM How to bind command to ContextMenu
我对使用 relativeSource 和 ancestorLevel 感到很困惑。
相对源用于从另一个元素获取源。但要成功做到这一点,您必须计算该元素处于什么级别。 (如何调试?) WPF中最容易混淆的地方
在我的例子中,我有上下文菜单,我想绑定数据源然后命令。绑定必须如何才能在我的虚拟机中获取命令?谢谢
<Page.DataContext>
<PDB:UsersViewModel x:Name="vm"/>
</Page.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--Page Header info content-->
<Grid Grid.Row="0">
<TextBlock Text="{Binding SelectedUser.Name}"/>
<TextBlock Text="{Binding ElementName=myGrd, Path=CurrentColumn.DisplayIndex}"/>
</Grid>
<!--Datagrid content-->
<DataGrid x:Name="myGrd"
SelectionMode="Single"
SelectionUnit="Cell"
CurrentItem="{Binding SelectedUser, Mode=TwoWay}"
CurrentColumn="{Binding CurrentColumn, Mode=TwoWay}"
IsReadOnly="True"
Grid.Row="1"
ItemsSource="{Binding FilteredUserList}"
AutoGenerateColumns="True"
CanUserAddRows="False"
>
<DataGrid.Resources>
<ContextMenu x:Key="ContextMenu">
<ContextMenu.Items>
<MenuItem Header="{Binding
RelativeSource={RelativeSource
FindAncestor,
AncestorType={x:Type Page},
AncestorLevel=4}, Path=vm}" />
</ContextMenu.Items>
</ContextMenu>
</DataGrid.Resources>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="ContextMenu" Value="{StaticResource ContextMenu}"/>
</Style>
</DataGrid.CellStyle>
</DataGrid>
</Grid>
您不能在 ContextMenu 中使用 RelativeSource,因为菜单不是可视化树的一部分。然而,这可以通过使用绑定源和 x:Reference.
来避免。
我假设您的 ViewModel 看起来像这样
public class UserViewModel
{
public string Header { get; set; }
public ICommand MyCommand { get; }
... more code
}
现在让我们绑定 VM 的 Header 和 MyCommand 属性
<ContextMenu x:Key="ContextMenu">
<ContextMenu.Items>
<MenuItem Header="{Binding Header, Source={x:Reference vm}}"
Command="{Binding MyCommand, Source={x:Reference vm}}"/>
</ContextMenu.Items>
</ContextMenu>
重要的部分是将 ViewModel 放在可视化树中的某个位置并设置它 x:Name,就像您在示例中所做的那样
<Page.DataContext>
<PDB:UsersViewModel x:Name="vm"/>
</Page.DataContext>
如果你还想进一步了解RelativeSource,这个question好像和你有同样的问题。基本上,绑定的路径必须是 DataContext.MyViewModelProperty
,绑定的 RelativeSource 必须是 DataContext 设置为 ViewModel 的元素。
我对使用 relativeSource 和 ancestorLevel 感到很困惑。 相对源用于从另一个元素获取源。但要成功做到这一点,您必须计算该元素处于什么级别。 (如何调试?) WPF中最容易混淆的地方
在我的例子中,我有上下文菜单,我想绑定数据源然后命令。绑定必须如何才能在我的虚拟机中获取命令?谢谢
<Page.DataContext>
<PDB:UsersViewModel x:Name="vm"/>
</Page.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--Page Header info content-->
<Grid Grid.Row="0">
<TextBlock Text="{Binding SelectedUser.Name}"/>
<TextBlock Text="{Binding ElementName=myGrd, Path=CurrentColumn.DisplayIndex}"/>
</Grid>
<!--Datagrid content-->
<DataGrid x:Name="myGrd"
SelectionMode="Single"
SelectionUnit="Cell"
CurrentItem="{Binding SelectedUser, Mode=TwoWay}"
CurrentColumn="{Binding CurrentColumn, Mode=TwoWay}"
IsReadOnly="True"
Grid.Row="1"
ItemsSource="{Binding FilteredUserList}"
AutoGenerateColumns="True"
CanUserAddRows="False"
>
<DataGrid.Resources>
<ContextMenu x:Key="ContextMenu">
<ContextMenu.Items>
<MenuItem Header="{Binding
RelativeSource={RelativeSource
FindAncestor,
AncestorType={x:Type Page},
AncestorLevel=4}, Path=vm}" />
</ContextMenu.Items>
</ContextMenu>
</DataGrid.Resources>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="ContextMenu" Value="{StaticResource ContextMenu}"/>
</Style>
</DataGrid.CellStyle>
</DataGrid>
</Grid>
您不能在 ContextMenu 中使用 RelativeSource,因为菜单不是可视化树的一部分。然而,这可以通过使用绑定源和 x:Reference.
来避免。我假设您的 ViewModel 看起来像这样
public class UserViewModel
{
public string Header { get; set; }
public ICommand MyCommand { get; }
... more code
}
现在让我们绑定 VM 的 Header 和 MyCommand 属性
<ContextMenu x:Key="ContextMenu">
<ContextMenu.Items>
<MenuItem Header="{Binding Header, Source={x:Reference vm}}"
Command="{Binding MyCommand, Source={x:Reference vm}}"/>
</ContextMenu.Items>
</ContextMenu>
重要的部分是将 ViewModel 放在可视化树中的某个位置并设置它 x:Name,就像您在示例中所做的那样
<Page.DataContext>
<PDB:UsersViewModel x:Name="vm"/>
</Page.DataContext>
如果你还想进一步了解RelativeSource,这个question好像和你有同样的问题。基本上,绑定的路径必须是 DataContext.MyViewModelProperty
,绑定的 RelativeSource 必须是 DataContext 设置为 ViewModel 的元素。