我完全混淆了relativeSource和ancestorLevel。相对源用于从其他元素获取源。但要想成功地做到这一点,你必须计算出这个元素的水平。(如何调试?(这是WPF中最令人困惑的部分。
在我的例子中,我有一个上下文菜单,我想绑定数据源,然后命令它。绑定必须如何才能在我的vm中获得命令?谢谢
<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,因为该菜单不是可视化树的一部分。但是,使用BindingSource和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的信息,这个问题似乎和你有同样的问题。基本上,绑定的Path必须是DataContext.MyViewModelProperty
,绑定的RelativeSource必须是DataContext设置为ViewModel的元素。