将可见性绑定到WPF dataGrid中的bool值

时间:2016-02-28 09:54:05

标签: wpf xaml datagrid visibility datagridcolumn

我知道由于DataGrid列不是Visual Tree的一部分,因此您无法将列的visibility属性直接绑定到VM中的boolean属性。你必须以另一种方式做到这一点。以下是我的方式:

public class LocalVm
{
    public static ObservableCollection<Item> Items
    {
        get
        {
            return new ObservableCollection<Item>
            {
                new Item{Name="Test1", ShortDescription = "Short1"}
            };
        }
    }

    public static bool IsDetailsModeEnabled
    {
        get { return true; }
    }
}

public class Item : INotifyPropertyChanged
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }


    private string _shortDescription;

    public string ShortDescription
    {
        get
        {
            return _shortDescription;
        }
        set
        {
            _shortDescription = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML:

<Window x:Class="Wpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Wpf"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        d:DataContext="{d:DesignInstance Type=local:LocalVm}"
        Title="MainWindow" Height="350" Width="525" 
        Name="MyWindow">

    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVis" />

        <DataGridTextColumn x:Key="ThatPeskyColumn"
                            Binding="{Binding Size}" 
                            Visibility="{Binding DataContext.IsDetailsModeEnabled, 
                            Source={x:Reference MyWindow}, 
                            Converter={StaticResource BoolToVis}}"/>

    </Window.Resources>

    <Grid>
        <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}" />
                <StaticResource ResourceKey="ThatPeskyColumn"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

但是,在我的xaml窗口中,&#34;可见性&#34; property:&#34;对象引用未设置为对象的实例&#34;。如果我删除源和转换器部分,则错误消失,但它没有正确绑定。我做错了什么?

提前致谢

1 个答案:

答案 0 :(得分:2)

正如我从您提供的代码中看到的,IsDetailsModeEnabled属性是静态的。在这种情况下,要绑定到静态属性,您可以将VM创建为静态资源,绑定到其静态属性并稍后将其设置为Window DataContext:

<Window.Resources>
    <local:LocalVm x:Key="vm" />
    <BooleanToVisibilityConverter x:Key="BoolToVis" />

    <DataGridTextColumn x:Key="ThatPeskyColumn"
                        Binding="{Binding ShortDescription}" 
                        Visibility="{Binding Path = IsDetailsModeEnabled, 
                        Source={StaticResource vm}, 
                        Converter={StaticResource BoolToVis}}"/>
</Window.Resources>
<Window.DataContext>
    <StaticResource ResourceKey="vm"/> 
</Window.DataContext>

另一方面,在这种情况下,更经典的方法是使用代理Freezable对象,描述为here

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); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

<强> XAML

<Window.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
    <BooleanToVisibilityConverter x:Key="BoolToVis" />

    <DataGridTextColumn x:Key="ThatPeskyColumn"
                        Binding="{Binding ShortDescription}" 
                        Visibility="{Binding Path=Data.IsDetailsModeEnabled, 
                        Source={StaticResource proxy}, 
                        Converter={StaticResource BoolToVis}}"/>
</Window.Resources>
相关问题