我在Style中访问特定的DataContext时遇到了一些问题
我有CatalogItem.joins(:item, :catalog).
where(items: { id: 4 }).pluck(:position).first
定义如下:
DataGrid
包含此<DataGrid Name="ReferenceDataGrid" ItemsSource="{Binding Items}" AutoGenerateColumns="False" RowHeaderWidth="0" IsReadOnly="True">
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Delete" Command="???" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
...
的{{1}}的{{1}}属性设置为
DataContext
我想将Page
绑定到DataGrid
并尝试了几种不同的方法来执行此操作:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
RelayCommand
//页面元素的名称设置为Root MenuItem
Command="{Binding DeleteCommand}"
我在Command="{Binding ElementName=Root, Path=DeleteCommand}"
的命令处理程序中设置了断点,但上面没有任何变化。
假设Command="{Binding ElementName=Root, Path=DataContext.DeleteCommand}"
包含Command="{Binding Path=DataContext.DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}}"
类型的元素
如果我在DeleteCommand
中定义命令,处理程序会被触发,所以看起来无论我上面做了什么,每个Items
的{{1}}似乎都是列表元素本身。
知道该怎么办吗?
修改
我还尝试将Foo
提取到一个单独的类中,并引用此而不是Foo
,因为我认为列表元素可能使用DataContext
作为DataGridRow
而不是DataContext
它指的是实例。不幸的是我错了。
答案 0 :(得分:1)
由于您只对一个地方的命令感兴趣,因此您可能会发现另一种有用的方法。 将contextmenu定义为可以获取该datacontext的资源,然后将其应用于datagrid行。 我已经在最初用于其他目的的样本上做了这个,所以我的对象和东西是不同的。
<DataGrid
ItemsSource="{Binding Users}"
Background="White"
Name="dg"
SelectedItem="{Binding SelectedUser}"
>
<DataGrid.Resources>
<ContextMenu x:Key="dgContextMenu"
DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=DataGrid}}">
<MenuItem Header="Up" Command="{Binding UpCommand}" />
</ContextMenu>
</DataGrid.Resources>
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="ContextMenu" Value="{StaticResource dgContextMenu}"/>
DataContext继承可视树,因此datagrid获取与页面或窗口相同的datacontext或其中的任何内容。 我的contextmenu实际上是在datagrid中,可以获取它的datacontext。
我还绑定了selecteditem,因此我可以使用它来确定点击了哪个特定行。
在窗口的viewmodel中,我有一个命令“UpCommand”,它使用所选用户的属性。
public RelayCommand UpCommand { get; set; }
public MainWindowViewModel()
{
UpCommand = new RelayCommand(UpExecute);
}
public User SelectedUser { get; set; }
private void UpExecute()
{
MessageBox.Show($"You Upped {SelectedUser.Title}");
}
您可以从用户中删除所选用户,或使用它的ID删除数据库中的记录或删除要执行的操作。
答案 1 :(得分:0)
<ContextMenu DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Delete" Command="{Binding DataContext.DeleteCommand}" />
</ContextMenu>
正如您在回答重复问题时所看到的那样,问题是:
ContextMenu在可视树之外
如果您不想将DeleteCommand
放入Items
中的条目,而不是Source
Binding
x:Reference
与<DataGrid Name="ReferenceDataGrid" ItemsSource="{Binding Items}" AutoGenerateColumns="False" RowHeaderWidth="0" IsReadOnly="True">
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding Path=DataContext, Source={x:Reference ReferenceDataGrid}}">
<MenuItem Header="Delete" Command="{Binding DeleteCommand}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
。
<div style={{ display: 'flex', flexDirection: 'column' }}>
</div>