我需要让我的DataGrid中的单元格反映条件规则......我已经到目前为止已经花了太多时间在这上面我希望有人可以帮助我吗?所以,这就是我的网格在运行时的当前状态:
在这里,您可以看到(忽略结果& 标准列),这里有三组两列需要关注。我目前正在将条件规则应用于 XPercVerified 列,但最终我希望 EF [X] 列根据相应PercVerified列中的值显示背景更改。另一个要点是,可以有任意数量的这两个列组合......
我目前遇到的问题是,我似乎只能应用规则来有条件地格式化整个Row。在上面的屏幕截图中,您可以看到 1PercVerified 列在第一行中有一个..这使整行变为绿色。代码如下:
Private Sub dgUnitMatrix_AutoGeneratingColumn(sender As Object, e As DataGridAutoGeneratingColumnEventArgs) Handles dgUnitMatrix.AutoGeneratingColumn
If (e.Column.Header.ToString().Contains("PercVerified")) Then
e.Column.CellStyle = TryCast(Application.Current.FindResource("PercVerified"), Style)
End If
End Sub
我们在这里调用 AutoGeneratingColumn 事件,当我们有一个 PercVerified 的列时,请调用应用程序资源样式:
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
ShutdownMode="OnMainWindowClose">
<Application.Resources>
<Style x:Key="PercVerified" TargetType="{x:Type DataGridCell}" >
<Style.Triggers>
<DataTrigger Binding="{Binding 1PercVerified}" Value="0">
<Setter Property="Background" Value="DarkRed"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Margin" Value="-2.0"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding 1PercVerified}" Value="1">
<Setter Property="Background" Value="DarkGreen"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Margin" Value="-2.0"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Application.Resources>
</Application>
Application.XAML 文件中存在。 我似乎有的另一个问题是,即使我可以让上述工作只在单元格(而不是行) - 我似乎只能在我的条件下确定(即绑定值必须相等 - 我不能做整数大于或小于?)...这是真的吗?
我已经开始向更远的地方看,因为我得到的印象是这种造型不适用于我想要的东西......所以,IValueConverters已经出现了几次,但我似乎无法获得这工作。是否值得我花时间研究这些只是为了发现它是另一个死胡同?
我可以提供任何人可能需要的任何额外信息......我非常渴望将其排序,因为我已经浪费了太多时间在WPF中的某些东西,这在Winforms中只是很容易!
修改
遵循J.H.的优秀答案。我已经使用作为对象值传递的DataRowView(而不是示例类对象)将其调整为wor。
在转换器中,我们正在创建变量dc。整个代码块已更改为:
' Get the cells DataContext as our data class '
Dim dc As DataRowView
dc = TryCast(cell.DataContext, DataRowView)
If IsNothing(dc) Then Exit Function
' Get the column number of the columnName that matches the Path
Dim ColNo As Integer
Dim idx As Integer = 0
For Each column As DataColumn In dc.DataView.Table.Columns
If column.ColumnName = path Then
ColNo = idx
End If
idx = idx + 1
Next
然后在进行条件格式的比较而不是:
Dim pv = dc.GetType().GetProperty(path).GetValue(dc)
我们使用
Dim pv As String = dc.Row.Item(ColNo).ToString()
除了由于差异而导致的一些其他变化之外,这也是一种享受!
答案 0 :(得分:1)
您可以使用IValueConverter执行此操作。您需要将DataGridCell传递给转换器。从单元格中,您可以获得datacontext和单元格的绑定。一旦你有了这些,一些反射可以获得PercVerifiedX字段的值。您可以检测EFX字段,然后获取适当的PercVerifiedX字段。
以下是一些代码,请注意我的属性名称与您的属性名称不同(无法使用数字启动属性),因此您可能需要调整一些代码。此外,我可以使用数字,但为DataTrigger.Value选择字符串只是为了表明它不是PercVerified值而是转换器的返回值。 并且,我把它混合了一点 - 红色为0 percs,绿色为1-3 percs,紫色为4+ percs。请参阅xaml和转换器的代码。
XAML
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication16"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:PercVerifiedConverter x:Key="PercVerifiedConverter" />
<Style x:Key="PercVerified" TargetType="{x:Type DataGridCell}" >
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource PercVerifiedConverter}}" Value="Red">
<Setter Property="Background" Value="DarkRed"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Margin" Value="-2.0"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource PercVerifiedConverter}}" Value="Green">
<Setter Property="Background" Value="DarkGreen"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Margin" Value="-2.0"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource PercVerifiedConverter}}" Value="Purple">
<Setter Property="Background" Value="Purple"></Setter>
<Setter Property="Foreground" Value="Yellow"></Setter>
<Setter Property="Margin" Value="-2.0"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<DataGrid ItemsSource="{Binding Data}" AutoGeneratingColumn="DataGrid_AutoGeneratingColumn" />
</Window>
.VB(带有评论的PITA是什么让颜色编码正确)
Imports System.Globalization
Class MainWindow
Public Sub New()
' This call is required by the designer. '
InitializeComponent()
Dim vm As New VM
vm.Data = New List(Of MyData) From {
New MyData() With {.Outcome = "Outcome 1", .Criterion = "1.1", .PercVerified1 = 1, .EF1 = "EP, ECH", .PercVerified3 = 0, .EF3 = "", .PercVerified4 = 0, .EF4 = "EWT"},
New MyData() With {.Outcome = "", .Criterion = "1.2", .PercVerified1 = 0, .EF1 = "", .PercVerified3 = 1, .EF3 = "O, EP", .PercVerified4 = 0, .EF4 = ""},
New MyData() With {.Outcome = "", .Criterion = "1.3", .PercVerified1 = 0, .EF1 = "", .PercVerified3 = 0, .EF3 = "O, EP", .PercVerified4 = 4, .EF4 = ""}
}
Me.DataContext = vm
End Sub
Private Sub DataGrid_AutoGeneratingColumn(sender As Object, e As DataGridAutoGeneratingColumnEventArgs)
If (e.Column.Header.ToString().Contains("PercVerified") Or e.Column.Header.ToString().Contains("EF")) Then
e.Column.CellStyle = TryCast(Me.FindResource("PercVerified"), Style)
End If
End Sub
End Class
Public Class MyData
Public Property Outcome As String
Public Property Criterion As String
Public Property PercVerified1 As String
Public Property EF1 As String
Public Property PercVerified3 As String
Public Property EF3 As String
Public Property PercVerified4 As String
Public Property EF4 As String
End Class
Public Class VM
Public Property Data As List(Of MyData)
End Class
Public Class PercVerifiedConverter
Implements IValueConverter
Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
Convert = Nothing
Dim cell As DataGridCell
Dim dc As MyData
' Get the DataGridCell passed in '
cell = TryCast(value, DataGridCell)
If IsNothing(cell) Then Exit Function
' Get the cells DataContext as our data class '
dc = TryCast(cell.DataContext, MyData)
If IsNothing(dc) Then Exit Function
' Get the cells column - need it for the binding '
Dim tc As DataGridTextColumn ' Assuming your cells are DataGridTextColumns '
tc = TryCast(cell.Column, DataGridTextColumn)
If IsNothing(tc) Then Exit Function
' Get the columns binding '
Dim b As Binding
b = TryCast(tc.Binding, System.Windows.Data.Binding)
If IsNothing(b) Then Exit Function
' Get the path off the binding '
Dim path As String
path = b.Path.Path ' Name of the property this column is bound to - PercVerified1, EF1, etc... '
' If one of the "EF" properties, convert path to the appropriate "PercVerified" path '
If path.Contains("EF") Then
Dim pvNum = path.Replace("EF", String.Empty) ' EF1 becomes 1 '
path = "PercVerified" + pvNum ' path is now PercVerified1 '
End If
If path.Contains("PercVerified") Then
Dim pv = dc.GetType().GetProperty(path).GetValue(dc)
If pv = 0 Then
Convert = "Red"
ElseIf pv >= 1 And pv <= 3 Then
Convert = "Green"
ElseIf pv >= 4 Then
Convert = "Purple"
End If
End If
End Function
Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
Throw New NotImplementedException()
End Function
End Class
并且,截图: