我从 CSV 文件中提取数据,在 DataTable 中解析它,然后将此 DataTable 设置为 DataGrid 的 ItemsSource。然后,我循环 DataTable 对数据进行一些验证,并且我想相应地为 DataGrid 行着色。
问题是,我无法根据DataTable行找到相应的DataGrid行。
这是我的代码:
Dim dg As New DataGrid
Dim dataTable as DataTable = ParseFile(filePath)
Dim statutList() As String = {"Saisi", "Validé", "Suspendu", "Annulé"}
dg.ItemsSource = dataTable.DefaultView
For Each row As DataRow In dataTable.Rows
'This line is what I tried, but it always returns nothing
Dim dgrow As DataGridRow = dg.ItemContainerGenerator.ContainerFromItem(row)
If Not statutList.Contains(row("Statut").ToString) Then
dgrow.Background = Brushes.Red
End If
Next
问题来自这一行,它不起作用:
Dim dgrow As DataGridRow = dg.ItemContainerGenerator.ContainerFromItem(row)
解决方案:
两种 mm8 解决方案均有效。就我而言,我使用了:
dg.UpdateLayout()
For Each row As DataRowView In dg.Items.OfType(Of DataRowView)
Dim dgrow As DataGridRow = dg.ItemContainerGenerator.ContainerFromItem(row)
If Not statutList.Contains(row("Statut").ToString) Then
dgrow.Background = Brushes.Red
End If
Next
最佳答案
正确的“WPF”方法是定义一个带有一个或多个数据触发器的 RowStyle,当该特定行的“Statut”列返回任何特定值时设置该行的背景颜色,例如:
<DataGrid x:Name="dg">
<DataGrid.Resources>
<SolidColorBrush x:Key="color" Color="Red" />
</DataGrid.Resources>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Statut}" Value="Saisi">
<Setter Property="Background" Value="{StaticResource color}" />
</DataTrigger>
<DataTrigger Binding="{Binding Statut}" Value="Validé">
<Setter Property="Background" Value="{StaticResource color}" />
</DataTrigger>
<DataTrigger Binding="{Binding Statut}" Value="Suspendu">
<Setter Property="Background" Value="{StaticResource color}" />
</DataTrigger>
<DataTrigger Binding="{Binding Statut}" Value="Annulé">
<Setter Property="Background" Value="{StaticResource color}" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
如果您稍微修改一下,您当前的代码隐藏方法就可以工作:
For Each row As DataRowView In dg.Items.OfType(Of DataRowView)
Dim dgrow As DataGridRow = dg.ItemContainerGenerator.ContainerFromItem(row)
If Not statutList.Contains(row("Statut").ToString) Then
dgrow.Background = Brushes.Red
End If
Next
请注意,如果 DataTable 包含大量行并且您尚未禁用 UI 虚拟化,则 ItemContainerGenerator.ContainerFromItem 方法实际上不会为可能已虚拟化的项目返回 DataGridRow 容器:
<DataGrid x:Name="dg" VirtualizingPanel.IsVirtualizing="False">.
如果您的 DataTable 包含大量行,显然禁用虚拟化可能会导致性能问题。
另请注意,需要在容器实际创建后执行代码,例如当窗口的 Loaded 事件发生时。
Class MainWindow
Dim statutList() As String = {"Saisi", "Validé", "Suspendu", "Annulé"}
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Dim dg As New DataGrid
Dim dataTable As DataTable = ParseFile(filePath)
dg.ItemsSource = dataTable.DefaultView
End Sub
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
For Each row As DataRowView In dg.Items.OfType(Of DataRowView)
Dim dgrow As DataGridRow = dg.ItemContainerGenerator.ContainerFromItem(row)
If Not statutList.Contains(row("Statut").ToString) Then
dgrow.Background = Brushes.Red
End If
Next
End Sub
...
End Class
关于wpf - 根据 DataTable 值对 DataGrid 行着色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41267720/