Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF DataGrid-单个单元格上条件格式的触发器_Wpf_Vb.net_Xaml_Datagrid_Styles - Fatal编程技术网

WPF DataGrid-单个单元格上条件格式的触发器

WPF DataGrid-单个单元格上条件格式的触发器,wpf,vb.net,xaml,datagrid,styles,Wpf,Vb.net,Xaml,Datagrid,Styles,我需要让数据网格中的单元格反映条件规则。。。我已经走了这么远,已经在这上面花了太多时间,我希望有人能帮助我?这就是我的网格当前运行时的外观: 在这里您可以看到(忽略结果和标准列),这里有三组两列需要关注。我目前正在将条件规则应用于XPercVerified列,但最终我希望EF[X]列根据相应percerverified列中的值显示背景更改。另一点是,这两个列的组合可以有任意数量 然而,我目前的问题是,我似乎只能有条件地将规则应用于整行的格式。在上面的屏幕截图中,您可以看到列1perccveri

我需要让数据网格中的单元格反映条件规则。。。我已经走了这么远,已经在这上面花了太多时间,我希望有人能帮助我?这就是我的网格当前运行时的外观:

在这里您可以看到(忽略结果标准列),这里有三组两列需要关注。我目前正在将条件规则应用于XPercVerified列,但最终我希望EF[X]列根据相应percerverified列中的值显示背景更改。另一点是,这两个列的组合可以有任意数量

然而,我目前的问题是,我似乎只能有条件地将规则应用于整行的格式。在上面的屏幕截图中,您可以看到列1perccverified在第一行有一个1。。这将使整行变为绿色。代码如下:

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
这里我们调用自动生成列事件,当我们有一个类似的列时,调用应用程序资源样式:

<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>
然后,在对条件格式进行比较时,而不是:

Dim pv = dc.GetType().GetProperty(path).GetValue(dc)
我们使用

Dim pv As String = dc.Row.Item(ColNo).ToString()

除了一些其他的变化,由于差异,这是一个对待工作

您可以使用IValueConverter来实现这一点。您需要将DataGridCell传递给转换器。从单元格中,可以获得单元格的datacontext和绑定。一旦你有了这些,一些反射可以得到percvifiedx字段的值。您可以检测EFX字段,然后获得相应的PercVerifiedX字段

下面是一些代码,请注意,我的属性名称与您的不太一样(不能以数字开头属性),因此您可能需要调整一些代码。此外,我可以使用数字,但选择DataTrigger.Value的字符串只是为了表明它不是PercVerified值,而是转换器的返回值。 我把它混合了一点——红色表示0%,绿色表示1-3%,紫色表示4+个百分点。请参阅xaml和转换器的代码

XAML


.VB(为了正确地进行颜色编码,注释中的PITA是多么棒啊)

导入系统。全球化
类主窗口
公共分新()
'设计器需要此调用。'
初始化组件()
将虚拟机设置为新虚拟机
vm.Data=来自的新列表(MyData){
带有{.output=“output 1”、.criteria=“1.1”、.percvified1=1、.EF1=“EP,ECH”、.percvified3=0、.EF3=”、.percvified4=0、.EF4=“EWT”}的新MyData(),
带有{.output=“”、.criteria=“1.2”、.PercVerified1=0、.EF1=“”、.PercVerified3=1、.EF3=“O,EP”、.PercVerified4=0、.EF4=“”)的新MyData(),
New MyData(),带有{.output=“”、.criteria=“1.3”、.percvified1=0、.EF1=“”、.percvified3=0、.EF3=“O,EP”、.percvified4=4、.EF4=“”}
}
Me.DataContext=vm
端接头
私有子DataGrid_AutoGeneratingColumn(发送方作为对象,e作为DataGrid AutogeneratingColumnEventArgs)
如果(e.Column.Header.ToString()包含(“PercVerified”)或e.Column.Header.ToString()包含(“EF”)),则
e、 Column.CellStyle=TryCast(Me.FindResource(“perceverified”),样式)
如果结束
端接头
末级
公共类MyData
作为字符串的公共属性结果
作为字符串的公共属性标准
公共属性PercVerified1作为字符串
公共属性EF1作为字符串
公共属性PercVerified3作为字符串
公共属性EF3作为字符串
公共属性PercVerified4作为字符串
公共属性EF4作为字符串
末级
公共类虚拟机
公共财产数据作为列表(MyData)
末级
公共类PercVerifiedConverter
实现IValueConverter
公共函数Convert(值作为对象,targetType作为类型,参数作为对象,区域性作为CultureInfo)作为对象实现IValueConverter.Convert
转换=无
Dim单元格作为DataGridCell
Dim dc作为MyData
'获取传入的DataGridCell'
单元格=TryCast(值,DataGridCell)
如果为Nothing(单元格),则退出函数
'获取单元格DataContext作为我们的数据类'
dc=TryCast(cell.DataContext,MyData)
如果为空(dc),则退出功能
'获取单元格列-绑定时需要它'
Dim tc As DataGridTextColumn“假设您的单元格是DataGridTextColumns”
tc=TryCast(cell.Column、DataGridTextColumn)
如果为Nothing(tc),则退出功能
'获取列绑定'
作为绑定的dimb
b=TryCast(tc.Binding、System.Windows.Data.Binding)
如果为Nothing(b),则退出函数
'将路径从绑定中移除'
将路径设置为字符串
path=b.path.path“此列绑定到的属性的名称-percvified1、EF1等…”
'如果是“EF”属性之一,请将路径转换为相应的“PercVerified”路径'
如果path.Contains(“EF”),则
Dim pvNum=path.Replace(“EF”,String.Empty)'EF1变为1'
path=“perceverified”+pvNum'路径现在是perceverified1'
如果结束
如果path.Contains(“percvied”),则
Dim pv=dc.GetType().GetProperty(路径).GetValue(dc)
如果pv=0,则
Convert=“红色”
如果pv>=1,则pv=4
Convert=“紫色”
如果结束
Dim pv As String = dc.Row.Item(ColNo).ToString()
<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>
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