简体   繁体   English

用于设置 DataTrigger 条件的 ItemsSource 列的依赖属性

[英]Dependency property for ItemsSource column to set DataTrigger condition

How would I properly bound to ItemsSource column via Dependency property of control (Datagrid), in order to set It's DataTrigger working?我如何通过控件(Datagrid)的依赖属性正确绑定到 ItemsSource 列,以设置它的 DataTrigger 工作?

My goal that works without dependency property:我的目标没有依赖属性:

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

And this is how I want It to work:这就是我希望它工作的方式:

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

My dependency property:我的依赖属性:

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); }
}

And this is how I try to bind control in XAML:这就是我尝试在 XAML 中绑定控件的方式:

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

More explanation: ItemsSource Persons is ObservableCollection of PersonsModel (which is type of Dependency property).更多解释:ItemsSource Persons是 PersonsModel 的 ObservableCollection(它是依赖属性的类型)。

I'm getting BindingExpression path error: 'NAME' property not found on 'object' ''ObservableCollection`1' error.我收到BindingExpression 路径错误:“名称”属性未在“对象”“ObservableCollection`1”错误上找到。

Based on your comments, your goal is to tell DataGrid to hide the row that has some property value == null. Hence, you have to assign the property's name to HideRow property and use a converter which uses reflection to get the property value and affect the style trigger.根据您的评论,您的目标是告诉 DataGrid 隐藏具有某些属性值 == null 的行。因此,您必须将属性的名称分配给 HideRow 属性并使用一个转换器,该转换器使用反射来获取属性值并影响样式触发器。

You have 2 options, the first one is simpler and you don't need the HideRow property at all:您有 2 个选项,第一个更简单,您根本不需要HideRow属性:

  1. Change RowStyle a bit, Here you will pass the name of the property as a ConverterParameter (so it might be Name, Age, etc...)稍微更改RowStyle ,在这里您将属性的名称作为 ConverterParameter 传递(因此它可能是 Name、Age 等...)
<DataGrid.RowStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding ., Converter={StaticResource NullPropertyToBoolConverter}, ConverterParameter=Name}" Value="True">
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.RowStyle>

Where NullPropertyToBoolConverter is NullPropertyToBoolConverter在哪里

public class NullPropertyToBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is PersonsModel person && parameter is string propertyName)
        {
            return typeof(PersonsModel).GetProperty(propertyName)?.GetValue(person, null) == null;
        }
        return value;
    }

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

The converter is defined in resources of one of DataGrid's parents (or in Application.xaml)转换器在 DataGrid 的父级之一的资源中定义(或在 Application.xaml 中)

<converters:NullPropertyToBoolConverter x:Key="NullPropertyToBoolConverter" />

It is getting the value of Name, and return true if it was null, and this will cause the row visibility to be Collapsed.它正在获取 Name 的值,如果它是 null 则返回 true,这将导致行可见性被折叠。

This option is suitable because in both options you have to define RowStyle but here you don't need to define a dependency property.这个选项是合适的,因为在这两个选项中你都必须定义 RowStyle 但在这里你不需要定义依赖属性。

  1. Here you would change HideRow type to string instead of PersonsModel, and use it like this:在这里,您可以将HideRow类型更改为字符串而不是 PersonsModel,并像这样使用它:
<ctl:My_DataGrid ItemsSource="{Binding Persons}" HideRow="Name" >

So, it might be Name, Age, etc...所以,它可能是姓名、年龄等……

You'd define <DataGrid.RowStyle> similar to this您将定义<DataGrid.RowStyle>类似于此

<DataGrid.RowStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Setter Property="Visibility">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource NullPropertyToBoolConverter2}">
                    <Binding Path="DataContext" RelativeSource="{RelativeSource Mode=Self}" />
                    <Binding Path="HideRow" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGrid}" />
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.RowStyle>

and define the Converter to return Collapse if property's value is null, otherwise Visible.并定义转换器以在属性值为 null 时返回 Collapse,否则返回 Visible。

public class NullPropertyToBoolConverter2 : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values[0] is Obj obj && values[1] is string str)
        {
            return typeof(Obj).GetProperty(str)?.GetValue(obj, null) == null ? Visibility.Collapsed : Visibility.Visible;
        }
        return Visibility.Visible;
    }

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM