我知道由于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;。如果我删除源和转换器部分,则错误消失,但它没有正确绑定。我做错了什么?
提前致谢
答案 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>