【问题标题】:Changing background color of DataGrid rows that are not visible更改不可见的 DataGrid 行的背景颜色
【发布时间】:2014-09-28 18:15:34
【问题描述】:

我有一个带有 AlternatingRowBackground(白色和蓝色)的 DataGrid。但是,某些选项可以使某些行只读(例如,行的后半部分),在这种情况下,背景将更改为浅灰色。 DataGrid 是动态填充的,因此所有这些背景更改都是在代码隐藏中完成的。

如果 DataGrid 的前半部分行是可编辑的,而后半部分是只读的,例如,代码是

if (Symmetric.IsChecked == true)
{
    int n = (nPoints % 2 == 0 ? nPoints / 2 : (nPoints + 1) / 2);
    for (int i = 1; i < n; i++)
    {
        //resultSections is the DataContext of the (DataGrid)SectionsGrid
        resultSections[i].IsReadOnly = false;
        var r = SectionsGrid.GetRow(i);
        if (r == null)
            continue;
        r.Background = (i % 2 == 0 ? Brushes.White : Brushes.AliceBlue);
    }
    for (int i = n; i < nPoints; i++)
    {
        resultSections[i].X = ProjectProperties.I.BeamLength - resultSections[nPoints - i - 1].X;
        resultSections[i].IsReadOnly = true;
        var r = SectionsGrid.GetRow(i);
        if (r == null)
            continue;
        r.Background = Brushes.LightGray;
    }
}

只要所有行都在视图中,此代码就可以正常工作。如果存在只能通过滚动查看的行,则 SectionsGrid.GetRow(i) 返回 null 并且背景不会改变。有没有办法在不绘制行的情况下设置行的背景?

我不知道如何使用 DataTriggers 在 .xaml 中执行此操作,我知道它通常用于定义不断变化的背景。问题是背景取决于是否选中了两个 CheckBoxes 中的任何一个(只能选中一个),而行为因 CheckBox 而异。此外,如果其中一个 CheckBoxes 被选中然后取消选中,则背景需要恢复为 AlternatingRowBackground,这又取决于行号。

编辑:

我意识到将 DataTrigger 设置为行的 DataContext 的 .IsReadOnly 属性可能有效,因此我创建了以下内容:

<Style x:Key="ReadOnlyCheck" TargetType="{x:Type DataGridRow}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsReadOnly}" Value="True">
            <Setter Property="Tag" Value="ReadOnly" />
            <Setter Property="Background" Value="LightGray"/>
        </DataTrigger>
    </Style.Triggers>

这适用于设置.IsReadOnly 将背景变为LightGray,但它仍然在超出“滚动范围”的行上失败。一旦我滚动,它们并没有变灰。

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    dataGrid 的虚拟化默认为开启,这意味着 dataGridRow 仅针对可见行生成。其他行只有在滚动后进入视口时才会生成。

    如果您想一次获取所有行,可以通过设置 VirtualizingStackPanel.IsVirtualizing="False" 来关闭 dataGrid 上的虚拟化。

    <DataGrid VirtualizingStackPanel.IsVirtualizing="False"/>
    

    此外,如果您不想关闭虚拟化,挂钩 DataGridRow 的 Loaded 事件,只要生成行并在处理程序中设置背景,就会触发该事件。

    <DataGrid>
        <DataGrid.ItemContainerStyle>
            <Style TargetType="DataGridRow">
                <EventSetter Event="Loaded" Handler="Row_Loaded"/>
            </Style>
        </DataGrid.ItemContainerStyle>
    </DataGrid>
    

    后面的代码:

    private void Row_Loaded(object sender, RoutedEventArgs e)
    {
        (sender as DataGridRow).Background = Brushes.AliceBlue;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-05-11
      • 1970-01-01
      • 2015-08-22
      • 2013-06-16
      • 1970-01-01
      • 2015-03-26
      • 2010-09-24
      • 2013-02-06
      • 2020-02-07
      相关资源
      最近更新 更多