zoukankan      html  css  js  c++  java
  • WPF DataGrid Visibility的绑定

      场景:根据配置文件显示DataGrid中的某些列。

      问题:Columns集合只是DataGrid的一个属性,这个集合在逻辑树或视觉树中是看不到的,也不会继承DataContext属性。

      通过网上查阅各种资料,方法可以归结以下几种,下面将一一展示。

      方法一:对DataGridColumn附加DataContext属性

      该方法需要用到一个帮助类(需要创建一个全局实例),具体内容如下:

    public class DataGridContextHelper
        {
            static DataGridContextHelper()
            {
    
                DependencyProperty dp = FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));
                FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid),
                new FrameworkPropertyMetadata
                   (null, FrameworkPropertyMetadataOptions.Inherits,
                   new PropertyChangedCallback(OnDataContextChanged)));
    
            }
    
            public static void OnDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                DataGrid grid = d as DataGrid;
                if (grid != null)
                {
                    foreach (DataGridColumn col in grid.Columns)
                    {
                        col.SetValue(FrameworkElement.DataContextProperty, e.NewValue);
                    }
                }
            }
        } 

      前台绑定示例

    <DataGridTextColumn x:Name="col2" Header="TestColumn"
                                        Visibility="{Binding (FrameworkElement.DataContext).Show,RelativeSource={RelativeSource Self},Converter={StaticResource cc}}"></DataGridTextColumn>

      后台绑定示例

    var binding = new Binding();
                binding.Mode = BindingMode.OneWay;
                binding.RelativeSource=new RelativeSource(RelativeSourceMode.Self);
                binding.Converter = new BooleanToVisibilityConverter();
                binding.Path=new PropertyPath("(FrameworkElement.DataContext).Show");
                BindingOperations.SetBinding(obj, DataGridColumn.VisibilityProperty, binding);

      方法二:通过Source直接与Vm绑定

      示例代码:

    var binding = new Binding();
                binding.Mode = BindingMode.OneWay;
                binding.Source = vm;
                binding.Converter = new BooleanToVisibilityConverter();
                binding.Path = new PropertyPath("Show");
                BindingOperations.SetBinding(obj, DataGridColumn.VisibilityProperty, binding);

      方法三:通过Source与VM的一个代理类进行绑定

      代理类

      Freezable可以继承DataContext即使它们不在视觉树或逻辑树中

    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 x:Name="dg" HorizontalAlignment="Left" VerticalAlignment="Top" Height="253" Width="436" ItemsSource="{Binding Persons}"
                      AutoGenerateColumns="False">
                <DataGrid.Resources>
                    <dgTest:BindingProxy x:Key="proxy" Data="{Binding}"/>
                </DataGrid.Resources>
                <DataGrid.Columns>
                    <DataGridTextColumn x:Name="col1" Header="TestColumn" Binding="{Binding Name}"></DataGridTextColumn>
                    <DataGridTextColumn x:Name="col2" Header="TestColumn"
                                        Visibility="{Binding (FrameworkElement.DataContext).Show,RelativeSource={RelativeSource Self},Converter={StaticResource cc}}"></DataGridTextColumn>
                    <DataGridTextColumn x:Name="col3" Header="TestColumn"
                                        Visibility="{Binding Data.Show,Source={StaticResource proxy},Converter={StaticResource cc}}"></DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>

      方法四:通过一个代理控件来实现

      代理控件与代理对象的解决方式类似,都是因为其可以继承DataContext属性,只是一个在逻辑树中看的到,一个看不到。示例如下:

    <FrameworkElement x:Name="dummyElement" Visibility="Collapsed"/>
        <DataGrid>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Test"
                                    Binding="{Binding Name}"
                                    Visibility="{Binding DataContext.IsEnable,
                                              Source={x:Reference dummyElement}}"/>
            </DataGrid.Columns>
        </DataGrid>
  • 相关阅读:
    顺序程序设计03 零基础入门学习C语言09
    数据类型,运算符和表达式05 零基础入门学习C语言06
    顺序程序设计01 零基础入门学习C语言07
    顺序程序设计01 零基础入门学习C语言07
    顺序程序设计02 零基础入门学习C语言08
    数据类型,运算符和表达式05 零基础入门学习C语言06
    分支程序设计01 零基础入门学习C语言10
    分支程序设计01 零基础入门学习C语言10
    VC++ 实现线程注入
    ISV 客户博客系列:Minitab通过Windows Azure推出云端Qeystone
  • 原文地址:https://www.cnblogs.com/maigc249/p/4561079.html
Copyright © 2011-2022 走看看