• WPF使用附加属性绑定,解决data grid列绑定不上的问题


    背景

    需要对datagrid的列header添加自定义属性,然后绑定,并根据不同的列header绑定不同的值,传统的加扩展类太麻烦,而附加属性的特点更适用于这种场景。

    1.xaml 代码

    <DataGridTemplateColumn Header="Control" HeaderStyle="{StaticResource controlHeader}"
    local:ControlView.ControlEnabled="{Binding Value.ControlMasterEnabled,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Source={StaticResource dataContextSource}}">

    2. 类声明附加属性

    public static bool GetControlEnabled(DependencyObject obj)
            {
                return (bool)obj.GetValue(ControlEnabledProperty);
            }
    
            public static void SetControlEnabled(DependencyObject obj, bool value)
            {
                obj.SetValue(ControlEnabledProperty, value);
            }
    
            // Using a DependencyProperty as the backing store for ControlEnabled.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty ControlEnabledProperty =
                DependencyProperty.RegisterAttached("ControlEnabled", typeof(bool), typeof(ControlView));

    然后在对应的headerstyle里绑定这个附加属性,就能针对不同的列设定不同的值了

    注意:附加属性绑定要使用括号,不然会绑定不上。

     
    <!--样式部分代码-->
    <CheckBox Grid.Column="1" IsChecked="{Binding Column.(local:ControlView.ControlEnabled),Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>

    另外由于DataGrid的列不在VisualTree里,所以如果在列里面使用附加属性,并绑定值到附加属性会绑定失败(使用相对绑定,查找ancestor方式),如果是使用x:Reference绑定则会出现cyclical dependency异常。

    三种方式解决绑定问题

    1.声明一个类,并放到resource里,对类里的属性绑定,datagrid列绑定使用资源数据

    public class BindingProxy : Freezable
    {
        #region Overrides of Freezable
    
        protected override Freezable CreateInstanceCore()
        {
            return new BindingProxy();
        }
    
        #endregion
    
        public object Data
        {
            get { return (object)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }
    
        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data", typeof(object),
                                         typeof(BindingProxy));
    }
     <DataGrid>
            <DataGrid.Resources>
                <local:BindingProxy x:Key="proxy" Data="{Binding}"/>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn Visibility="{Binding Data.MyColumnVisibility,
                                                    Source={StaticResource proxy}}"/>
            </DataGrid.Columns>
        </DataGrid>

    2. 不够elegant的方法,将datagrid那一列放到resource里。

    <DataGridTemplateColumn x:Key="controlColumn" Header="Control" HeaderStyle="{StaticResource controlHeader}"
    local:ControlView.ControlEnabled="{Binding Value.ControlMasterEnabled,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,Type={x:Type local:ControlView}}}">

    然后在datagrid里使用资源的方式加入列

                <DataGrid.Columns>
                    <StaticResource ResourceKey="controlColumn"/>

    3. 使用已有的的对象绑定值,再在列里面使用(和第一种方式类似,不过不用自己写一个类)(本人推荐)

    <DiscreteObjectKeyFrame x:Key="dataContextSource" Value="{Binding}"/>

    使用方式

    <DataGridTemplateColumn x:Name="controlColumn" HeaderStyle="{StaticResource controlHeader}"
                                            local:ControlView.ControlEnabled="{Binding Value.ControlMasterEnabled,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Source={StaticResource dataContextSource} }">

    参考:

    https://stackoverflow.com/questions/22073740/binding-visibility-for-datagridcolumn-in-wpf/22074985

    作者:qidong
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    平衡的括号(栈)
    二叉树遍历
    Ohana Cleans Up0101
    Missing number
    Django框架之模板层
    Django框架之路由层、视图层
    Django框架
    Django初识
    前端之bootstrap
    前端之BOM、DOM
  • 原文地址:https://www.cnblogs.com/qidong/p/10968122.html
Copyright © 2020-2023  润新知