【问题标题】:Is it possible to conditionally format a WPF datagrid row based on an aggregate?是否可以基于聚合有条件地格式化 WPF 数据网格行?
【发布时间】:2020-12-03 09:13:48
【问题描述】:

我从 SQL 加载数据网格,然后将其绑定

myDataGrid.ItemsSource = dt.DefaultView 

dt 是我的数据表。我知道如何根据其中一列中的显式值突出显示一行:

<DataTrigger Binding="{Binding someNumberA}" Value="1">
   <Setter Property="Background" Value="Red" />
</DataTrigger>

但是假设我有两列 someNumberA 和 someNumberB 并且想要基于布尔聚合突出显示该行,例如如果 sNA-sNB > 5 则为红色。这在 XAML 中是否可能,如果没有,那么我还能怎么做,因为我从未使用方法显式创建类,只是直接从数据表中加载?现在我确实有办法通过在 SQL 中创建一个布尔列来使其工作,所以我有明确的 T/F 值,然后突出显示该值并隐藏该列。感谢您的任何意见。

根据我使用转换器的建议,我想出了一个非常好的解决方案。

<Style TargetType="{x:Type DataGridRow}">
            <Style.Triggers>
                <DataTrigger Value="False">
                    <DataTrigger.Binding>
                        <MultiBinding Converter="{StaticResource CheckGreaseTolerance}">
                            <Binding Path = "GREASE_UPPER"/>
                            <Binding Path ="GREASE_LOWER"/>
                        </MultiBinding>
                    </DataTrigger.Binding>
                    <Setter Property="Background" Value="Red" />
                </DataTrigger>
            </Style.Triggers>
        </Style>

以及它调用的类:

Public Class CheckGreaseTolerance
    Implements IMultiValueConverter

    Public Function Convert(values() As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IMultiValueConverter.Convert
        Dim GU As Decimal = CDec(values(0))
        Dim GL As Decimal = CDec(values(1))
        If GU - GL > 2 Then
            Return False
        Else
            Return True
        End If

    End Function

【问题讨论】:

    标签: c# sql wpf vb.net xaml


    【解决方案1】:

    如果您的数据项具有可修改的视图模型,您将添加一个布尔属性来公开聚合结果,就像您在 SQL 中使用单独列的替代方法一样。

    在 XAML 中,您可以value converters 用于不同类型的聚合函数,并在数据触发器中使用它们。您可以创建IValueConverter 并绑定您的数据行或IMultiValueConverter 以直接传递数据行的特定属性,甚至可以绑定其他属性,例如来自父数据上下文。

    someNumberA - someNumberB > 5 示例的值转换器可能如下所示,将 DataGridRow 作为值和 double 参数进行比较。

    public class SampleAggregateConverter : IValueConverter
    {
       public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
       {
          var dataRowView = (DataRowView)value;
          return (double)dataRowView["someNumberA"] - (double)dataRowView["someNumberB"] > (double)parameter;
       }
    
       public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
       {
          throw new InvalidOperationException("This conversion is one-way only.");
       }
    }
    

    然后在您的行样式中,您可以通过绑定行并使用转换器来应用数据触发器。

    <DataTrigger Value="True">
       <DataTrigger.Binding>
          <Binding Converter="{StaticResource SampleAggregateConverter}">
             <Binding.ConverterParameter>
                <system:Double>5.0</system:Double>
             </Binding.ConverterParameter>
          </Binding>
       </DataTrigger.Binding>
       <Setter Property="Background" Value="Red" />
    </DataTrigger>
    

    绑定有点冗长,因为直接分配ConverterParameter 会导致它作为string 传递给转换器。多值转换器可用于绑定参数值。

    【讨论】:

    • 非常感谢您的回复,我没想过使用转换器(好吧,我以前从未使用过转换器,所以这可能是原因。我使用了您的想法并对其进行了一些调整以达到为我工作。我将使用我的解决方案更新我的代码,以防有人碰巧看到并需要它。
    猜你喜欢
    • 2022-11-07
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 2016-05-03
    • 2011-12-20
    • 2012-09-14
    • 2021-12-22
    • 1970-01-01
    相关资源
    最近更新 更多