【问题标题】:MVVM How to bind command to ContextMenuMVVM 如何将命令绑定到 ContextMenu
【发布时间】:2020-03-10 11:48:32
【问题描述】:

我对使用 relativeSource 和祖先级别完全感到困惑。 相对源用于从其他元素获取源。但是要成功地做到这一点,您必须计算该元素的级别。 (如何调试?)这是 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>

【问题讨论】:

  • 这能回答你的问题吗? WPF: Binding a ContextMenu to an MVVM Command
  • 是的,我确实读过这篇文章。但在我看来,这个解决方案是错误的。他们在说什么: 1. 在 A 类中,您引用了另一个要访问的 B 类。 2.在A类你有财产。然后将 B 类属性设置为 A 类属性,然后从 A 类属性中尝试访问 B 类属性...
  • 如何在评论中写新行?
  • 您可以在 meta.stackoverflow.com 上找到此类问题的答案:Is there a way to break line in comment?
  • 关键词是“ContextMenu不在可视化树中”和“PlacementTarget”。

标签: wpf mvvm binding contextmenu


【解决方案1】:

您不能在 ContextMenu 中使用 RelativeSource,因为菜单不是可视化树的一部分。不过,这可以通过使用 Binding Source 和 x:Reference 来避免。

我假设您的 ViewModel 看起来像这样

public class UserViewModel
{
    public string Header { get; set; }
    public ICommand MyCommand { get; }
    ... more code
}

现在让我们绑定虚拟机的 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 的元素。

【讨论】:

    猜你喜欢
    • 2011-04-04
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多