当前位置:首页 > Windows程序 > 正文

WPF DataGrid Visibility的绑定

2021-05-25 Windows程序

  场景:根据配置文件显示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属性,只是一个在逻辑树中看的到,一个看不到。示例如下:

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/71170.html