wpf问题~解决DataGrid列列头及可见性的绑定问题

原创 2017年07月18日 17:20:41

之前写过的一遍文章,在这里直接贴出来。
场景:根据配置文件显示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>

WPF中DataGrid使用自定义列绑定数据

WPF中DataGrid使用自定义列绑定数据
  • hit_why
  • hit_why
  • 2017年03月24日 14:24
  • 2732

wpf之datagrid 序号列

方法一:在datagrid最前面添加序列号 窗体加载时: private void MdiChild_Loaded(object sender, RoutedEventArgs e) ...
  • u010121883
  • u010121883
  • 2015年10月31日 22:01
  • 2678

WPF DataGrid使用 自动显示行号、全选、三级联动、拖拽

1.DataGrid的使用自动显示行号(修复删除行时行号显示不正确) dgTool.LoadingRow += new EventHandlerDataGridRowEventArgs (dgTool...
  • lanshengsheng2012
  • lanshengsheng2012
  • 2013年10月24日 10:46
  • 6388

WPF-DataGrid后台动态生成列

DataGrid后台动态生成列 Now that you know the basics of the Silverlight DataGrid and how to specify...
  • yqj234
  • yqj234
  • 2016年03月14日 15:49
  • 4950

WPF中设置DataGrid中DataGridColumn列的普通样式和编辑样式

DataGridColumn的派生类:   一般情况下DataGridBoundColumn和DataGridComboBoxColumn足以满足多数列的样式,如果需要自定义列样式...
  • zhgyuhui
  • zhgyuhui
  • 2013年02月18日 11:20
  • 2236

WPF中DataGrid数据绑定(泛型和datatable)

前台代码: ...
  • kwy15732621629
  • kwy15732621629
  • 2016年07月16日 19:53
  • 3536

DataGrid数据转换——IValueConverter实现DataGrid数据转换

背景: 使用ASP.NET做B/S系统时,可以方便地在GRIDVIEW DATAList等数据控件中,使用自定义的代码逻辑,比如 使用 这样的调用, GetBalance()为在codebehi...
  • u011948354
  • u011948354
  • 2015年01月19日 15:41
  • 289

WPF Grid + DataGrid多表头 动态列实现

Grid + DataGrid简单实现了多表头,动态列。Mark~
  • i0703mtf
  • i0703mtf
  • 2016年12月12日 20:34
  • 2453

WPF中DataGrid 添加checkbox实现全选、多选

在机房合作项目中,有一个窗体是这样子的               简单介绍一下:就是通过查询出正在上机的学生,可以通过勾选前面的checkbox,选中该行,然后可以进行部分下机和全部下机。如...
  • kwy15732621629
  • kwy15732621629
  • 2016年07月26日 14:41
  • 6770

datagrid动态加载列(续)

之前有一篇博客写到了如何动态加载datagrid的列,上次只是介绍如何动态动态表头,并没有将数据添加到datagrid中,本次主要来说如何将数据库中的数据,动态添加到每一列中。      先说一下为...
  • u013038643
  • u013038643
  • 2016年04月24日 17:25
  • 1375
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:wpf问题~解决DataGrid列列头及可见性的绑定问题
举报原因:
原因补充:

(最多只允许输入30个字)