简体   繁体   English

WPF DataGrid - 如何设置正确的 DataTrigger 绑定到单元格的数据源(而不是行的源)

[英]WPF DataGrid - How to setup correct DataTrigger binding to cell's data source (and not row's source)

Trying to setup the background of a cell dependend on a cell-object property in a WPF DataGrid I get an error, that the property is not found (but on the row-object):尝试根据 WPF DataGrid 中的单元格对象属性设置单元格的背景,我收到一个错误,即找不到该属性(但在行对象上):

System.Windows.Data Error: 40: BindingExpression path error: 'IsOn' property not found on 'object' ''MyRow' (HashCode=48826322)'. System.Windows.Data 错误:40:BindingExpression 路径错误:在“对象”“MyRow”(HashCode = 48826322)上找不到“IsOn”属性。 BindingExpression:Path=IsOn;绑定表达式:路径=IsOn; DataItem='MyRow' (HashCode=48826322); DataItem='MyRow' (HashCode=48826322); target element is 'DataGridCell' (Name='');目标元素是'DataGridCell'(名称=''); target property is 'NoTarget' (type 'Object')目标属性是“NoTarget”(类型“对象”)

I wonder, why the DataTrigger Binding is addressing the row object "MyRow", since the DataTrigger is defined for/inside a CellStyle.我想知道,为什么 DataTrigger 绑定正在处理 object“MyRow”行,因为 DataTrigger 是为 CellStyle 定义的/在 CellStyle 内部定义的。

XAML: XAML:

<DataGrid Name="tblTest" Grid.Column="2" IsReadOnly="True" AutoGenerateColumns="True">
    <DataGrid.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
            <Setter Property="Background" Value="PaleGreen" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsOn}" Value="True">
                    <Setter Property="Background" Value="Red"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.CellStyle>
</DataGrid>

C# C#

class MyCell
{
    public MyCell( string v)
    {
        Value = v;
    }
    public string Value { get; set; }
    public bool IsOn { get => Value == "one";  }
    public override string ToString()
    {
        return Value;
    }
}

class MyRow
{
    public MyCell One { get; set;  }
    public MyCell Two { get; set;  }
}

void SetupTestTable()
{
    List<MyRow> data = new();
    data.Add(new MyRow
    {
        One = new MyCell("one"),
        Two = new MyCell("two")
    });
    tblTest.ItemsSource = data;
}

在此处输入图像描述

So how to bind against the cell object "MyCell" correctly?那么如何正确绑定单元格 object “MyCell”?

DataGridCells have the same DataContext as DataGridRow - there are many obstacles to do differently in general-purpose manner. DataGridCells 与 DataGridRow 具有相同的 DataContext - 以通用方式做不同的事情有很多障碍。 So single DataGrid.CellStyle won't work所以单个 DataGrid.CellStyle 不起作用

I will use AutoGeneratingColumn to create cell styles for each column.我将使用AutoGeneratingColumn为每一列创建单元格 styles。 However they will be based on existing style which is stored in DataGrid.Resources.但是,它们将基于存储在 DataGrid.Resources 中的现有样式。

<DataGrid Name="tblTest" Grid.Column="2" IsReadOnly="True" 
          AutoGenerateColumns="True"
          AutoGeneratingColumn="tblTest_AutoGeneratingColumn">
    <DataGrid.Resources>
        <Style TargetType="{x:Type DataGridCell}" x:Key="ColoredCellStyle">
            <Setter Property="Background" Value="Cyan" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Tag.IsOn, RelativeSource={RelativeSource Self}}" Value="True">
                    <Setter Property="Background" Value="Red"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.Resources>
</DataGrid>

I'm using binding to Tag instead of DataContext, because DataContext is MyRow object.我正在使用绑定到 Tag 而不是 DataContext,因为 DataContext 是MyRow object。 In Tag there will be MyCell objects.Tag中会有MyCell对象。 It is achieved in event handler:它是在事件处理程序中实现的:

private void tblTest_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    if (e.Column is DataGridTextColumn tc && tc.Binding is Binding binding)
    {
        // unique value for each column
        var property = binding.Path.Path;

        // DataGrid reference to get Resources
        var dg = (DataGrid)sender;

        // new cell style which inherits trigger from ColoredCellStyle and binds Tag to MyCell property
        var cellStyle = new Style
        {
            TargetType = typeof(DataGridCell),
            BasedOn = (Style)dg.Resources["ColoredCellStyle"],
            Setters =
            {
                new Setter
                { 
                    Property = DataGridCell.TagProperty, 
                    Value = new Binding(property)
                }
            }
        };

        tc.CellStyle = cellStyle;
    };
}

彩色细胞

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM