2016-12-21 81 views
1

我從CSV文件中提取數據,在DataTable中解析數據,然後將此DataTable設置爲DataGrid的ItemsSource。然後,我循環DataTable對數據進行一些驗證,並且我想相應地爲DataGrid行着色。基於DataTable值爲DataGrid行着色

問題是,我找不到相應的DataGrid行基於DataTable行。

這裏是我的代碼:

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) 

SOLUTION:

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

回答

1

這樣做,這將是定義與設置該行的背景顏色的一個或多個數據觸發一個RowStyle的正確「WPF」方式時,該「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 

注意,ItemContain erGenerator.ContainerFromItem方法實際上不會返回可能已經被虛擬化掉項的DataGridRow容器如果DataTable包含很多行,你有沒有禁用虛擬化的用戶界面:

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

我很想使用wpf方法,但這只是數據檢查代碼的一小部分。我必須檢查一些單元格與其他幾個值(+200)。您的代碼隱藏方法代碼不起作用。 – Naucle

+1

「不工作」意味着什麼?你是否遇到異常或會發生什麼?您需要在容器實際創建完成後執行此代碼,例如,在窗口的Loaded事件發生時。你不能遍歷窗口構造函數中的容器。 – mm8

+0

我在dgrow上得到一個NullReferenceException。 DataGrid實際上在檢查部分之前加載(For Each循環在dg.ItemsSource = dataTable.DefaultView填充容器之後) – Naucle