由DataGridTextColumn不能获取到父级DataContext引发的思考
2014-01-28 21:46
267 查看
在项目中使用DataGrid需要根据业务动态隐藏某些列,思路都是给DataGrid中列的Visibility属性绑定值来实现(项目使用MVVM),如下
如果不是在DataGridTextColumn上绑定,那么这段代码是可以工作的,问题出在DataGridTextColumn上,我们来看它的继承层次
它不是FrameworkElement的派生类,所以它不具有DataContext属性,也就是说,即使DataGrid有DataContext,DataGridTextColumn也不能得到它,Visibility找不到DataContext自然绑定不上,这就是为什么上面的绑定失效的原因,同样其他类型的列也有同样的问题。那么如何优雅地解决问题呢?国际友人给出了这样一个方法,既然DataGridTextColumn不能从父级那里得到DataContext,那么直接给她的Visibility指定一个DataContext,实现如下
首先创建一个可以承载DataContext的绑定代理类BindingProxy
然后将这个BindingProxy当作资源,获得DataContext
将DataGridTextColumn的Visibility的DataContext指定为这个BindingProxy
BindingProxy.cs
MainWindow.xaml
这样就能优雅地解决了这个问题
原文地址http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
Demo:WPF_DataContextAndDataGridTextColumn_Sample.rar
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Visibility="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGrid}},Path=DataContext.IsVisible,Converter={StaticResource BooleanToVisibilityConverter}}"></DataGridTextColumn>
如果不是在DataGridTextColumn上绑定,那么这段代码是可以工作的,问题出在DataGridTextColumn上,我们来看它的继承层次
它不是FrameworkElement的派生类,所以它不具有DataContext属性,也就是说,即使DataGrid有DataContext,DataGridTextColumn也不能得到它,Visibility找不到DataContext自然绑定不上,这就是为什么上面的绑定失效的原因,同样其他类型的列也有同样的问题。那么如何优雅地解决问题呢?国际友人给出了这样一个方法,既然DataGridTextColumn不能从父级那里得到DataContext,那么直接给她的Visibility指定一个DataContext,实现如下
首先创建一个可以承载DataContext的绑定代理类BindingProxy
然后将这个BindingProxy当作资源,获得DataContext
将DataGridTextColumn的Visibility的DataContext指定为这个BindingProxy
BindingProxy.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; namespace WPF_DataContext_Sample { public class BindingProxy:Freezable { protected override Freezable CreateInstanceCore() { return new BindingProxy(); } public object DataContext { get { return (object)GetValue(DataContextProperty); } set { SetValue(DataContextProperty, value); } } // Using a DependencyProperty as the backing store for DataContext. This enables animation, styling, binding, etc... public static readonly DependencyProperty DataContextProperty = DependencyProperty.Register("DataContext", typeof(object), typeof(BindingProxy), new PropertyMetadata(null)); } }
MainWindow.xaml
<Window x:Class="WPF_DataContext_Sample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wpfDataContextSample="clr-namespace:WPF_DataContext_Sample" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <wpfDataContextSample:Converter x:Key="Converter"></wpfDataContextSample:Converter> <wpfDataContextSample:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"></wpfDataContextSample:BindingProxy> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="0.1*"/> </Grid.RowDefinitions> <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Students}"> <DataGrid.Columns> <DataGridTextColumn Header="Id" Binding="{Binding Id}"></DataGridTextColumn> <!--这样的绑定会失败--> <!--<DataGridTextColumn Header="Name" Binding="{Binding Name}" Visibility="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGrid}},Path=DataContext.IsShow,Converter={StaticResource BooleanToVisibilityConverter}}"></DataGridTextColumn>--> <DataGridTextColumn Header="Name" Binding="{Binding Name}" Visibility="{Binding DataContext.IsShow,Source={StaticResource BindingProxy},Converter={StaticResource Converter}}"></DataGridTextColumn> <DataGridTextColumn Header="Sex" Binding="{Binding Sex}"></DataGridTextColumn> </DataGrid.Columns> </DataGrid> <StackPanel Orientation="Horizontal" Grid.Row="1"> <Button Width="100" Height="30" Content="隐藏Name" Click="ButtonBase_OnClick"></Button> </StackPanel> </Grid> </Window>
这样就能优雅地解决了这个问题
原文地址http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
Demo:WPF_DataContextAndDataGridTextColumn_Sample.rar
相关文章推荐
- wpf——datagrid中如何获取DataGridTextColumn等某行某列的值
- DataGridTemplateColumn 如何获取内部控件
- 关于在extjs中使用column布局,不能显示textfield的标签(fieldLabel)解决方法
- C#获取ButtonColumn 的DataTextField 值 的方法
- 让EditText不能自动获取焦点
- Android 如何让EditText不能自动获取焦点
- 关于在extjs中使用column布局,不能显示textfield的标签(fieldLabel)解决方法
- EditText不能获取文本问题
- wpf 中设置DataGridTextColumn的文本对齐方式
- 让EditText不能自动获取焦点
- 在WPF中获取DataGridTemplateColumn模板定义的内容控件
- 让EditText不能自动获取焦点
- 让EditText不能自动获取焦点
- AndroidTextView的跑马灯效果,解决复杂布局不能获取焦点的问题
- static关键字,引发的spring普通类获取spring的bean的思考
- 让EditText不能自动获取焦点
- AlertDialog中EditText不能获取焦点以及不宽度不能自动铺满的完美解决方案
- 让EditText不能自动获取焦点
- [赏析]stack overflow引发的关于获取知识的思考
- ListView里面有EditTextView,解决弹出键盘后EditView不能获取焦点的问题