Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法从样式中使用父级的DataContext_C#_Wpf_Binding - Fatal编程技术网

C# 无法从样式中使用父级的DataContext

C# 无法从样式中使用父级的DataContext,c#,wpf,binding,C#,Wpf,Binding,从样式中访问特定DataContext时遇到一些问题。 我有一个DataGrid定义如下: <DataGrid Name="ReferenceDataGrid" ItemsSource="{Binding Items}" AutoGenerateColumns="False" RowHeaderWidth="0" IsReadOnly="True"> <DataGrid.Resources> <Style TargetType="DataGr

从样式中访问特定DataContext时遇到一些问题。
我有一个
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>
    ...
我想将
RelayCommand
绑定到
菜单项
,并尝试了几种不同的方法:

  • Command=“{Binding DeleteCommand}”
  • Command=“{Binding ElementName=Root,Path=DeleteCommand}”
    //页面元素的名称设置为Root
  • Command=“{Binding ElementName=Root,Path=DataContext.DeleteCommand}”
  • Command=“{Binding Path=DataContext.DeleteCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}}}”
我在
DeleteCommand
的命令处理程序中设置了一个断点,但上面的任何变体都没有设置断点

假设
Items
包含
Foo
类型的元素
如果我在
Foo
中定义该命令,则会触发处理程序,因此无论我在上面做了什么,每个
DataGridRow
DataContext
似乎都是列表元素本身

你知道怎么办吗

编辑:

我还尝试将
DataContext
提取到一个单独的类中,并引用该类而不是
相对Self
,因为我认为列表元素可能使用
相对Self
作为其
DataContext
而不是它引用的
页面
实例。不幸的是,我错了。

因为您只对一个地方的命令感兴趣,所以有另一种方法可以做到这一点,您可能会发现它很有用。
<ContextMenu  DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
    <MenuItem Header="Delete"  Command="{Binding DataContext.DeleteCommand}" />
</ContextMenu>
将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}"/>

您可以从用户中删除所选用户,或者使用其ID从数据库中删除记录,或者执行任何删除操作。

可能重复的Nope也不起作用。也许我必须做一些不同的事情,因为我使用的是样式而不是数据模板?你会只使用与DataGrid相同的datacontext中的命令吗?@Andy到目前为止,我每个页面/窗口都只有一个datacontext等。我真的不想用这些东西把模型类弄乱,所以我将它们存储在页面的datacontext中。我还需要更新DataContext中的几个其他属性,以便将其中的部分提取到单独的属性中不会带来任何好处实际上。。。这是件好事。我将发布一个解决方案。我已经尝试过这个解决方案,但它不像我在评论中说的那样有效。它对我有效。是否确实在对象中有GridRowDataContextDeleteCmd,该对象是DataGridRow的DataContext?请查看设置了
ContextMenu
DataContext
。我正在尝试重现该问题,它显示错误4。我还使用
PresentationTraceSources.TraceLevel=High
尝试了您的解决方案,但没有效果。我认为事件处理程序可能是这里的解决方案。@Rekshino我复制粘贴了您的代码,以确保我这边没有输入错误,但它仍然不起作用。命令实例已存在。我在DataGrid旁边创建了一个按钮,让它成功触发这个命令,所以我假设命令实例本身不是问题所在。
<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>
<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}"/>
    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}");
    }