Coloring WPF DataGridRows one by one

左心房为你撑大大i 提交于 2020-01-04 11:39:29

问题


I'm making a WPF program which is able to color the rows in a DataGrid one by one in red using the for loop and I've encountered something weird. If the DataGrid has more than 40 rows of data from a database table, it doesn't color all the rows.

Here's the code I'm using.

private void Red_Click(object sender, RoutedEventArgs e)
{
    for (int i = 0; i < dataGrid1.Items.Count; i++)
    {
        DataGridRow row = (DataGridRow)dataGrid1.ItemContainerGenerator.ContainerFromIndex(i);
        if (row != null)
        {
            row.Background = Brushes.Red;
        }
    }
}

Is there any other way to color the rows one by one through other methods or is this some kind of fault in wpftoolkit?


回答1:


If you want to define colours for each row and you have a property on the items the rows display you can use an ItemsContainerStyle to set the row colour. In the example below you would have a property called ItemColour on your items in the grid which would define the background row colour. The binding binds from the row to the item the row contains.

 <dg:DataGrid.ItemContainerStyle>
    <Style
       TargetType="{x:Type dg:DataGridRow}"
       BasedOn="{StaticResource {x:Type dg:DataGridRow}}">
       <Setter
          Property="Background"
          Value="{Binding ItemColour}" />
    </Style>
 </dg:DataGrid.ItemContainerStyle>

But you might not want a property ItemColour on your items as they might be your business model. This is where a ViewModel comes into its own. you define a middle layer that wraps your business layer and the ItemColour property based on some custom logic.




回答2:


If you want to set background to all rows of your grid you can define a new row style object and set the its Background property; this should change all the rows background all at once without the need to iterate through them. Smth like this:

dataGrid1.RowStyle = new Style(typeof(DataGridRow));
dataGrid1.RowStyle.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Red))); 

There is also a chance that you need to change background of your datagrid rows according to states of the data objects behind them. In this case you can setup a custom style with triggers in your xaml and assign it the rowstyle. I guess smth like this:

<Window.Resources>
    <Style x:Key="customDataGridRowStyle" TargetType="{x:Type DataGridRow}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Test1}" Value="1">
                <Setter Property="Background" Value="Red"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
..
<DataGrid .. DataGrid.RowStyle ="{StaticResource customDataGridRowStyle}" >
..

in the example above red background is set to the row whenever it's "Test1" property gets value "1"

hope this helps, regards




回答3:


The rows that are not visible on the screen won't be abled to be coloured using this method as they are virtualised away and dont actually exist. In the style below im binding to a property IsRed to turn the rows between red and their default colour (put this in the resources of the from with the datagrid on it)

        <Style
           TargetType="{x:Type dg:DataGridRow}"
           BasedOn="{StaticResource {x:Type dg:DataGridRow}}">
           <Style.Triggers>
              <DataTrigger
                 Binding="{Binding ElementName=self, Path=IsRed}"
                 Value="True">
                 <Setter
                    Property="Background"
                    Value="Red" />
              </DataTrigger>
           </Style.Triggers>
        </Style>

i have a dependency property on my form called IsRed, this could also be any property that implements INotifyPropertyChanged (dependency properties notify about their changes)

  public Boolean IsRed {
     get { return (Boolean)GetValue(IsRedProperty); }
     set { SetValue(IsRedProperty, value); }
  }

  // Using a DependencyProperty as the backing store for IsRed.  This enables animation, styling, binding, etc...
  public static readonly DependencyProperty IsRedProperty =
      DependencyProperty.Register("IsRed", typeof(Boolean), typeof(Window1), new UIPropertyMetadata(false));

then in my xaml i have the declaration at the top

<Window
   x:Class="Grids.Window1"
   x:Name="self">

which means i can reference it with an element name binding (a technique i find useful)

With the code as ive outlined all your button click would have to do would be

  private void Button_Click(object sender, RoutedEventArgs e) {
     IsRed = !IsRed;
  }


来源:https://stackoverflow.com/questions/2046104/coloring-wpf-datagridrows-one-by-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!