背景

需要对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

WPF使用附加属性绑定,解决data grid列绑定不上的问题的更多相关文章

  1. [WinForm] DataGridView 绑定 DT && ComboBox 列绑定 Dict

    一  需求介绍 一般像枚举类型的数据,我们在数据库里存储着诸如(1.2.3.4-)或者("001"."002"."003"-)此类,但是界面 ...

  2. WPF Binding ElementName方式无效的解决方法--x:Reference绑定

    原文:WPF Binding ElementName方式无效的解决方法--x:Reference绑定 需求: 背景:Grid的有一个TextBlock name:T1和一个ListBox,ListBo ...

  3. DevExpress WPF v19.1:Data Grid/Tree List等控件功能增强

    行业领先的.NET界面控件DevExpress 日前正式发布v19.1版本,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WPF v19.1中新增的一些控件及部 ...

  4. WPF PasswordBox不支持绑定解决方法

    原文:WPF PasswordBox不支持绑定解决方法 PasswordBox的Password属性因为安全原因不支持直接绑定,可以使用依赖属性实现.直接插入代码 public class Passw ...

  5. WPF使用后台C#代码创建Grid

    笔者刚刚接触WPF,菜鸟一枚,在做一个练手程序时遇到这样一个需求,创建一个新的Grid并将其添加至一个ListView中,要求Grid及其子元素应按一定顺序给Name属性赋值,直接使用XAML创建的话 ...

  6. 【WPF学习】第二十九章 元素绑定——将元素绑定到一起

    数据banding的最简单情形是,源对象时WPF元素而且源属性是依赖性属性.前面章节解释过,依赖项属性具有内置的更改通知支持.因此,当在源对象中改变依赖项属性的值时,会立即更新目标对象中的绑定属性.这 ...

  7. WPF教程三:学习Data Binding把思想由事件驱动转变为数据驱动

    之前大家写代码都喜欢用事件驱动,比如说鼠标输入的click事件.初始化的内容全部放在窗体加载完毕的load事件,等等,里面包含了大量的由事件触发后的业务处理代码.导致了UI和业务逻辑高度耦合在一个地方 ...

  8. 14、手把手教你Extjs5(十四)模块字段和Grid列的定义[2]

    model和columns生成好了,下面要修改一下Module.js和Grid.js中的代码,使其能够协同工作. /** * 一个模块的主控界面的容器,用来安放各个模块控件以及协调他们之间的关系 */ ...

  9. 给angularJs grid列上添加自定义按钮

    由于项目需要在angular 显示的表格中添加按钮,多次查询资料终于找到解决方法.就是给columnDefs 上的列增加 cellTemplate,同时绑定对应的触发事件,代码如下 columnDef ...

随机推荐

  1. android调用其他apk的activity

    <img src="https://img-blog.csdn.net/20160322114625025" alt="" />启动另一个apk的工 ...

  2. TensorFlow数据集(二)——数据集的高层操作

    参考书 <TensorFlow:实战Google深度学习框架>(第2版) 一个使用数据集进行训练和测试的完整例子. #!/usr/bin/env python # -*- coding: ...

  3. 两句话跳转QQ聊天界面 通过web方式

    NSString *qq=[NSString stringWithFormat:"]; NSURL *url2 = [NSURL URLWithString:qq]; if ([[UIApp ...

  4. SOA思想

    参考:https://www.cnblogs.com/renzhitian/p/6853289.html 是什么 SOA service-oriented architecture 面向服务的体系结构 ...

  5. rsync服务的安装与配置

    rsync 服务的安装配置与客户端的同步操作   1. 使用xinetd服务运行rsync服务: 服务器端: 1.关闭selinux,设置iptables开放xinetd的873端口 2. yum - ...

  6. nodejs 学习(4) express+mongoose

    一.关于安装和启动: 1.设置环境变量:D:\Program Files\MongoDB\bin 2.启动时需要cd到bin 目录,然后 mongod --dbpath "D:\mongdb ...

  7. shell脚本实现自动化备份

    1.备份规则: 在生产环境中有若干服务器需要定时将服务器中应用程序,以及数据库等进行备份.要求在本地服务器中保存近一周的备份,备份服务器中保存最近一月的备份文件.                    ...

  8. 响应式Spring Cloud初探

    响应式Spring Cloud初探 分类:工程原文链接:The Road to Reactive Spring Cloud作者:  JOSH LONG译者: helloworldtang日期:JUNE ...

  9. APICloud手机APP开发

    官网 http://docs.apicloud.com/

  10. Spring框架学习——AOP的开发

    一.AOP开发中的相关术语. ——JoinPoint(连接点):指那些可以被拦截到的点.比如增删改查方法都可以增强,这些方法就可以被称为是连接点. ——PointCut:切入点,真正被拦截的点,指对哪 ...