简体   繁体   中英

C# WPF DataGrid Bind Row background to Property found in DataRow

I need to bind a background of a DataRow, to a property of an object attached to the DataRow. What I have done is:

  • I have extended the DataRow class, to have a 'Tag' property which is of type [object].
  • Example:

    myDataTable.Rows.Cast<ExtendedDataRow>().ToList(){r => {
        r.Tag = Brushes.Green;
    });
    

    So basically for every Row, there is a Tag property which is a Brush, Green. I need to bind my DataTable to this dataset, and bind each row to the Tag property.

    What I have tried:

    <DataGrid ItemsSource="{Binding myDataTable}">
        <DataGrid.RowStyle>
            <Style TargetType="DataGridRow">
                <Setter Property="Background" Value="{Binding Tag.Background}" />
            </Style>
        </DataGrid.RowStyle>
    </DataGrid>
    

    But it does not seem to 'pick up' the Tag item when I am trying to bind to it. Do I need to create an ItemTemplate for this? (I have tried it, also did not work)

    : The dataset is binding successfully, and in the code in the ViewModel I can see the Tag items for each row is populated. :数据集已成功绑定,在ViewModel的代码中,我可以看到每行的Tag项已填充。

    Thanks in advance

    : It has been requested to see how my ExtendedDataRow class is used: :已被要求查看如何使用我的ExtendedDataRow类:

    public class ExtendedDataTable : DataTable {
        public ExtendedDataTable()
            : base() {
        }
    
        public ExtendedDataTable(string tableName)
            : base(tableName) {
        }
    
        public ExtendedDataTable(string tableName, string tableNamespace)
            : base(tableName, tableNamespace) {
        }
    
        // Return the RowType as ExtendedDataRow instead of DataRow
        protected override Type GetRowType() {
            return typeof(ExtendedDataRow);
        }
    
        // Use the RowBuilder to return an ExtendedDataRow instead of DataRow
        protected override DataRow NewRowFromBuilder(DataRowBuilder builder) {
            return new ExtendedDataRow(builder);
        }
    }
    
    public class ExtendedDataRow : DataRow {
        public ExtendedDataRow()
            : base(null) {
        }
    
        public ExtendedDataRow(DataRowBuilder rb)
            : base(rb) {
        }
    
        // The tag object attached to the ExtendedDataRow
        public object Tag { get; set; }
    }
    

    : To bind to the ExtendedDataTable instead of a normal DataTable, you have to fill a normal DataTable, and use its IDataReader to fill the dataset of the ExtendedDataTable: :要绑定到ExtendedDataTable而不是普通的DataTable,必须填充普通的DataTable,并使用其IDataReader填充ExtendedDataTable的数据集:

    myDt = new ExtendedDataTable();
    dt = new DataTable();
    var dt = GetDataTable("SELECT * FROM SomeTable");
    var reader = dt.DataSet.CreateDataReader(dt);
    myDt.Load(reader);
    

    I did every thing as expected , just like you've done .

    I noticed the problem by looking in the output window :

          System.Windows.Data Error: 40 : BindingExpression path error: 'Tag' property not found on 'object' ''DataRowView' (HashCode=30296746)'. BindingExpression:Path=Tag; DataItem='DataRowView' (HashCode=30296746); target element is 'DataGridRow' (Name=''); target property is 'Background' (type 'Brush')
    

    DataRow is some how internally wrapped with something called a DataRowView

    A quick glance in msdn - DataRowView.Row

    XAML :

      <DataGrid CanUserAddRows="False" ItemsSource="{Binding Table}">                     
            <DataGrid.RowStyle>
                <Style TargetType="DataGridRow">
                    <Setter Property="Background" Value="{Binding Row.Tag, Mode=OneWay}" />
                </Style>
            </DataGrid.RowStyle>
        </DataGrid>
    

    The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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