views:

718

answers:

3

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?

A: 

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;
  }
Aran Mulholland
I see. If the rows don't exist as they are not seen on the datagrid, does that mean it's not possible to color the rows with more than one color (eg: White/Black/Grey or Yellow/Red/Blue)? Thanks for the answer btw. I still feel there has to be other ways to solve this.
KenNY
+1  A: 

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

serge_gubenko
+1  A: 

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.

Aran Mulholland
Can you provide an example on this ViewModel? I'm still not good when it comes to binding properties.
KenNY
http://sites.google.com/site/wpfprojects/ download the coloured rows example, and mark this question as answered. there might be some other projects there that you might like to look at as well
Aran Mulholland
+1 for spelling coloured with a 'u', oh, and thanks for the example.
panamack