DataGridRow排序后,背景颜色将降至默认值

时间:2013-12-17 08:46:04

标签: c# .net wpf

我的问题是:
在我的WPF应用程序中,我有来自Extended WPF Toolkit的标准DataGrid ColorPicker 。当用户在ColorPicker中选择新颜色时,任务是更改DataGridRow的背景颜色。我用下一个代码制作了它:

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;
            }
        }

它运行良好,DataGridRow的背景发生了变化,但在排序或滚动DataGrid之后,所有选择的背景颜色都会降为默认值(白色)。 我不知道为什么会这样,并寻求帮助。 Here我找到了有用的信息,但我只能在XAML中使用此方法...也许有办法在С#中更改 InactiveSelectionHighlightBrushKey

1 个答案:

答案 0 :(得分:0)

默认情况下,DataGrid使用虚拟化来提高性能 - 它仅为DataGridRow的当前可见项实例化ItemsSource,并根据需要创建(或回收)更多项(例如,用户调整窗口大小或滚动)。

要解决您的问题,您可以执行以下操作:

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();
}

但是,我建议在WPF中阅读MVVM和动态样式,而不是修改视图直接将视图绑定到模型并仅修改模型:

  1. 扩展您的数据模型以包含新的样式属性
  2. 将DataGridRow.Style绑定到模型的样式属性
  3. 当用户选择颜色时,修改相应的模型样式
  4. 例如:

    <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;
        }
    }