问题
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