为 WPF DataGridRow 逐一着色

发布于 2024-08-18 01:23:01 字数 558 浏览 7 评论 0原文

我正在制作一个 WPF 程序,它能够使用 for 循环将 DataGrid 中的行逐一着色为红色,但我遇到了一些奇怪的事情。如果 DataGrid 包含数据库表中超过 40 行的数据,它不会为所有行着色。

这是我正在使用的代码。

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

是否有其他方法可以通过其他方法将行逐一着色,或者这是 wpftoolkit 中的某种错误?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱本泡沫多脆弱 2024-08-25 01:23:01

如果要为每行定义颜色,并且行显示的项目有一个属性,则可以使用 ItemsContainerStyle 来设置行颜色。在下面的示例中,网格中的项目将有一个名为 ItemColour 的属性,该属性将定义背景行颜色。绑定从行绑定到行包含的项目。

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

但您可能不希望您的商品具有 ItemColour 属性,因为它们可能是您的业务模型。这就是 ViewModel 发挥作用的地方。您定义一个中间层来包装您的业务层和基于某些自定义逻辑的 ItemColour 属性。

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.

可爱咩 2024-08-25 01:23:01

如果您想为网格的所有行设置背景,您可以定义一个新的行样式对象并设置其背景属性;这应该立即更改所有行背景,而不需要迭代它们。像这样:

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

您也有可能需要根据数据网格行背后的数据对象的状态更改数据网格行的背景。在这种情况下,您可以在 xaml 中设置带有触发器的自定义样式并为其分配行样式。我想是这样的:

<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}" >
..

在上面的示例中,只要“Test1”属性获取值“1”,红色背景就会设置为该行,

希望这有帮助,尊敬

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

§对你不离不弃 2024-08-25 01:23:01

屏幕上不可见的行将无法使用此方法着色,因为它们已被虚拟化并且实际上并不存在。在下面的样式中,我绑定到属性 IsRed 以将行在红色和默认颜色之间转换(将其放入带有数据网格的资源中),

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

我的表单上有一个名为 IsRed 的依赖属性,这也可以是任何实现 INotifyPropertyChanged 的​​属性(依赖属性通知它们的更改),

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

然后在我的 xaml 中,我在顶部有声明,

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

这意味着我可以使用元素名称绑定引用它(我发现有用的技术)

使用我概述的所有代码单击按钮必须做的是

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

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;
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文