Silverlight DataGridTextColumn Binding Visibility
我需要一个Silverlight DataGrid中的列可以基于viewmodel中的值来显示/折叠.要完成这个,我试图将Visibility属性绑定到viewmodel.但是我很快发现Visibility属性不是DependencyProperty,因此它不能绑定.
为了解决这个问题,我试图将自己的DataGridTextColumn子类化.有了这个新类,我创建了一个DependencyProperty,它最终将更改推送到DataGridTextColumn.Visibility属性.这样做很好,如果我不数据绑定.当我将数据绑定到我的新属性时,它会失败,并出现AG_E_PARSER_BAD_PROPERTY_VALUE异常.
public class MyDataGridTextColumn : DataGridTextColumn { #region public Visibility MyVisibility public static readonly DependencyProperty MyVisibilityProperty = DependencyProperty.Register("MyVisibility",typeof(Visibility),typeof(MyDataGridTextColumn),new PropertyMetadata(Visibility.Visible,OnMyVisibilityPropertyChanged)); private static void OnMyVisibilityPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) { var @this = d as MyDataGridTextColumn; if (@this != null) { @this.OnMyVisibilityChanged((Visibility)e.OldValue,(Visibility)e.NewValue); } } private void OnMyVisibilityChanged(Visibility oldValue,Visibility newValue) { Visibility = newValue; } public Visibility MyVisibility { get { return (Visibility)GetValue(MyVisibilityProperty); } set { SetValue(MyVisibilityProperty,value); } } #endregion public Visibility MyVisibility }
这是XAML的一小部分.
<DataGrid ....> <DataGrid.Columns> <MyDataGridTextColumn Header="User Name" Foreground="#FFFFFFFF" Binding="{Binding User.UserName}" MinWidth="150" CanUserSort="True" CanUserResize="False" CanUserReorder="True" MyVisibility="{Binding Converter={StaticResource BoolToVisibilityConverter},Path=ShouldShowUser}"/> <DataGridTextColumn .../> </DataGrid.Columns> </DataGrid>
几个重要的事实.
>转换器的确定在上面的本地资源中.
>转换器是正确的,它在解决方案中使用了许多其他地方.
>如果我用“折叠”替换MyVisibility属性的{Binding}语法,那么列实际上消失了.
>如果我创建一个新的DependencyProperty(即字符串Foo),并绑定到它,我也收到AG_E_PARSER_BAD_PROPERTY_VALUE异常.
有人有什么想法为什么这不工作?
解决方法
首先,您需要继承DataGrid.
public class DataGridEx : DataGrid { public IEnumerable<string> HiddenColumns { get { return (IEnumerable<string>)GetValue(HiddenColumnsproperty); } set { SetValue(HiddenColumnsproperty,value); } } public static readonly DependencyProperty HiddenColumnsproperty = DependencyProperty.Register ("HiddenColumns",typeof (IEnumerable<string>),typeof (DataGridEx),new PropertyMetadata (HiddenColumnsChanged)); private static void HiddenColumnsChanged(object sender,DependencyPropertyChangedEventArgs args) { var dg = sender as DataGrid; if (dg==null || args.NewValue == args.OldValue) return; var hiddenColumns = (IEnumerable<string>)args.NewValue; foreach (var column in dg.Columns) { if (hiddenColumns.Contains ((string)column.GetValue (NameProperty))) column.Visibility = Visibility.Collapsed; else column.Visibility = Visibility.Visible; } } }
DataGridEx类根据DataGridColumn及其后代的x:Name名称添加新的DP来隐藏列.
在您的XAML中使用:
<my:DataGridEx x:Name="uiData" DataContext="{Binding SomeDataContextFromTheVM}" ItemsSource="{Binding Whatever}" HiddenColumns="{Binding HiddenColumns}"> <sdk:DataGridTextColumn x:Name="uiDataCountOfItems"> Header="Count" Binding={Binding CountOfItems}" </sdk:DataGridTextColumn> </my:DataGridEx>
您需要将这些添加到您的viewmodel或您使用的任何数据上下文.
private IEnumerable<string> _hiddenColumns; public IEnumerable<string> HiddenColumns { get { return _hiddenColumns; } private set { if (value == _hiddenColumns) return; _hiddenColumns = value; PropertyChanged (this,new PropertyChangedEventArgs("HiddenColumns")); } } public void SomeWhereInYourCode () { HiddenColumns = new List<string> {"uiDataCountOfItems"}; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。