You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过DataGrid依赖属性绑定ItemsSource列实现DataTrigger

问题:通过DataGrid依赖属性绑定ItemsSource列实现DataTrigger生效

现有无需依赖属性的可行实现

<Style TargetType="DataGridRow">
   <Style.Triggers>
      <DataTrigger Binding="{Binding NAME}" Value="{x:Null}">
        <Setter Property="Visibility" Value="Collapsed"/>
      </DataTrigger>
   </Style.Triggers>
</Style>

期望的依赖属性实现方式

<Style TargetType="DataGridRow">   
   <Style.Triggers>
      <DataTrigger Binding="{Binding HideRow, ElementName=_myGrid}" Value="{x:Null}">
         <Setter Property="Visibility" Value="Collapsed"/>
      </DataTrigger>
   </Style.Triggers>
</Style>

自定义DataGrid的依赖属性代码

public static DependencyProperty HideRowProperty =
                        DependencyProperty.Register("HideRow", typeof(PersonsModel), typeof(My_DataGrid), 
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

///<summary>Property for hiding rows, based on column name</summary>
public PersonsModel HideRow
{
    get { return (PersonsModel)GetValue(HideRowProperty); }
    set { SetValue(HideRowProperty, value); }
}

尝试的XAML绑定代码

<ctl:My_DataGrid ItemsSource="{Binding Persons}" HideRow="{Binding Persons.NAME}">

错误信息

BindingExpression路径错误:在对象“ObservableCollection`1”上未找到“NAME”属性。


修正方案

1. 调整依赖属性设计

将依赖属性改为存储要检查的属性名称(字符串类型),而非实体对象:

public static DependencyProperty HideRowProperty =
    DependencyProperty.Register("HideRow", typeof(string), typeof(My_DataGrid), 
        new FrameworkPropertyMetadata(null));

///<summary>要检查的属性名称,当该属性值为Null时隐藏行</summary>
public string HideRow
{
    get { return (string)GetValue(HideRowProperty); }
    set { SetValue(HideRowProperty, value); }
}

2. 实现属性路径转换器

创建转换器,根据传入的属性名称动态获取数据项的属性值:

public class PropertyPathConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length != 2 || values[0] == null || values[1] == null)
            return null;
        
        var dataItem = values[0];
        var propertyName = values[1].ToString();
        var propertyInfo = dataItem.GetType().GetProperty(propertyName);
        
        return propertyInfo?.GetValue(dataItem);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

3. 修改XAML样式与绑定

先在资源中声明转换器:

<Window.Resources>
    <local:PropertyPathConverter x:Key="PropertyPathConverter"/>
</Window.Resources>

再调整DataGridRow的Style,通过多值绑定关联当前行数据与DataGrid的依赖属性:

<Style TargetType="DataGridRow">   
   <Style.Triggers>
      <DataTrigger Value="{x:Null}">
          <DataTrigger.Binding>
              <MultiBinding Converter="{StaticResource PropertyPathConverter}">
                  <Binding/> <!-- 绑定当前行的PersonsModel实例 -->
                  <Binding Path="HideRow" ElementName="_myGrid"/> <!-- 绑定DataGrid的依赖属性 -->
              </MultiBinding>
          </DataTrigger.Binding>
          <Setter Property="Visibility" Value="Collapsed"/>
      </DataTrigger>
   </Style.Triggers>
</Style>

4. 修正DataGrid的绑定配置

<ctl:My_DataGrid x:Name="_myGrid" ItemsSource="{Binding Persons}" HideRow="NAME">

问题根源说明

  1. 原绑定HideRow="{Binding Persons.NAME}"错误:Persons是ObservableCollection<PersonsModel>集合对象,本身没有NAME属性,只有集合内的单个PersonsModel实例才具备该属性。
  2. 原依赖属性类型为PersonsModel,无法实现动态指定要检查的列,改为字符串类型存储属性名更符合需求。
  3. DataGridRow的DataContext是集合中的单个PersonsModel实例,因此需要通过多值绑定同时获取当前行数据和DataGrid的依赖属性值,再通过转换器完成属性值的动态判断。

内容的提问来源于stack exchange,提问作者Lucy82

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 07:10:12