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>
  • 相关阅读:
    Java 蓝桥杯 算法训练 貌似化学
    Java 蓝桥杯 算法训练 貌似化学
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    JAVA-蓝桥杯-算法训练-字符串变换
    Ceph:一个开源的 Linux PB 级分布式文件系统
    shell 脚本监控程序是否正在执行, 如果没有执行, 则自动启动该进程
  • 原文地址:https://www.cnblogs.com/maigc249/p/4561079.html
Copyright © 2011-2022 走看看