我有一个带有AlternatingRowBackground(白色和蓝色)的 DataGrid 。但是,某些选项可以使某些行只读(例如,行的后半部分),在这种情况下,背景将更改为LightGrey。 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,而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,但它仍然在“滚动范围”之外的行上失败。滚动后,它们没有变灰。
答案 0 :(得分:0)
默认情况下,对于dataGrid ,虚拟化处于启用状态,这意味着仅为可见行生成dataGridRow。其他行仅在滚动后进入视口时生成。
如果您想一次获取所有行,可以通过设置VirtualizingStackPanel.IsVirtualizing="False"
来关闭dataGrid上的虚拟化。
<DataGrid VirtualizingStackPanel.IsVirtualizing="False"/>
此外,如果您不想关闭虚拟化, 挂钩DataGridRow的加载事件 ,每当生成行并在其中设置背景时会触发处理程序。
<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;
}