微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

silverlight – 如何绑定DataGridColumn.Visibility?

我有一个类似于以下帖子的问题:

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] 举报,一经查实,本站将立刻删除。

相关推荐