【问题标题】:Binding visibility to bool value in WPF dataGrid将可见性绑定到 WPF dataGrid 中的布尔值
【发布时间】:2016-06-11 09:35:07
【问题描述】:

我知道,由于 DataGrid 列不是可视树的一部分,因此您无法将列的可见性属性直接绑定到 VM 中的布尔属性。你必须以另一种方式来做。以下是我的做法:

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 窗口中,“可见性”属性出现错误:“对象引用未设置为对象的实例”。如果我删除源和转换器部分,错误就会消失,但它没有正确绑定。我做错了什么?

提前致谢

【问题讨论】:

    标签: wpf xaml datagrid visibility datagridcolumn


    【解决方案1】:

    从您提供的代码中可以看出,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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-01
      • 2013-01-15
      • 1970-01-01
      • 2018-07-28
      • 2010-12-06
      • 2014-10-17
      • 2019-02-09
      • 1970-01-01
      相关资源
      最近更新 更多