当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - DataGridRow Background-color is dropping to default after sorting

问题描述:

my problem is:

In my WPF-application I have standart DataGrid and ColorPicker from Extended WPF Toolkit. The task is to change background color of DataGridRow when user select a new color in ColorPicker. I made it with next code:

private void ColorPicker_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs<Color> e)

{

DataGridRow[] selectedDataGridRows = new DataGridRow[DataGrid1.SelectedItems.Count];

for (int i = 0; i < DataGrid1.SelectedItems.Count; i++)

{

selectedDataGridRows[i] = (DataGridRow)DataGrid1.ItemContainerGenerator.ContainerFromItem(DataGrid1.SelectedItems[i]);

Style style = new Style(typeof(DataGridRow));

style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(e.NewValue)));

selectedDataGridRows[i].Style = style;

}

}

It works well and background of DataGridRow changes, BUT after sorting or scrolling DataGrid all chosen background colors drop to default (white).

I don`t know why it happens and ask for help. Here I find useful information, but I can use this method only in XAML ... Maybe there is a way to change InactiveSelectionHighlightBrushKey in С#?

网友答案:

By default, DataGrid uses virtualization to improve performance - it instantiates DataGridRow only for the currently visible items of the ItemsSource and it creates (or recycles) more as necessary (e.g. when users resizes the window or scrolls).

To fix your immediate problem you can do something like this:

public UserControl1() 
{
    InitializeComponent();
    ...
    DataGrid1.LoadingRow += DataGrid1_LoadingRow;
}

Dictionary<int, Style> rowStyles = new Dictionary<int, Style>();

void DataGrid1_LoadingRow(object sender, DataGridRowEventArgs e)
{
    int rowIndex = DataGrid1.Items.IndexOf(e.Row.Item);
    if (rowStyles.ContainsKey(rowIndex))
    {
        e.Row.Style = rowStyles[rowIndex];
    }
    else
    {
        e.Row.Style = null;
    }
}

void ColorPicker_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs<Color> e)
{
    Style style = new Style(typeof(DataGridRow));
    style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(e.NewValue)));
    foreach (object selectedItem in DataGrid1.SelectedItems)
    {
        int rowIndex = DataGrid1.Items.IndexOf(selectedItem);
        rowStyles[rowIndex] = style;
    }
    DataGrid1.Items.Refresh();
}

However, I would recommend reading up on MVVM and dynamic styling in WPF and instead of modifying the view directly bind the view to model and modify the model only:

  1. Extend your data model to contain new style property
  2. Bind DataGridRow.Style to the model's style property
  3. When user picks a color, modify appropriate model style

For example:

<DataGrid Name="DataGrid1">
    <DataGrid.RowStyle>
        <Style TargetType="{x:Type DataGridRow}">
            <Setter Property="Background" Value="{Binding rowBackground}"/>
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

DataTable Model { get; set; }

public UserControl1()
{
    InitializeComponent();

    this.Model = new DataTable() { Locale = CultureInfo.CurrentCulture };
    this.Model.Columns.Add("a", typeof(int));
    this.Model.Columns.Add("b", typeof(string));
    this.Model.Columns.Add("rowBackground", typeof(Brush));
    this.Model.Rows.Add(1, "one", Brushes.White);
    this.Model.Rows.Add(2, "two", Brushes.White);
    this.Model.Rows.Add(3, "three", Brushes.White);
    this.Model.AcceptChanges();

    DataGrid1.ItemsSource = this.Model.DefaultView;
}

void ColorPicker_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs<Color> e)
{
    Brush brush = new SolidColorBrush(e.NewValue);
    foreach (DataRowView selectedItem in DataGrid1.SelectedItems)
    {
        selectedItem["rowBackground"] = brush;
    }
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: