我正在尝试使用复选框控制列的可见性(这是在WPF 4.0中实现的)。
以下是我的XAML代码片段:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
</Window.Resources>
<CheckBox x:Name="GeneralDetailsVisible" Content="General Details" Margin="5"/>
<DataGridTextColumn Header="Crew"
Binding="{Binding Path=Crew}"
Visibility="{Binding ElementName=GeneralDetailsVisible,
Converter={StaticResource BoolToVisConverter},
Path=IsChecked}">
</DataGridTextColumn>
现在我知道BooleanToVisibilityConverter转换器正在工作,因为我将其绑定到文本块上,我可以看到我期望的值。如果我手动将值输入到列可见性属性中,则可以正常工作。但是当我绑定它时就不行了。我做错了什么?
答案:
Quartermeister指向了答案。他指向的页面有点误导人,因为帖子上列出的代码不起作用,你必须查看示例代码。
这是我的最终工作代码,供其他遇到此问题的人使用:
转换器将我们的ViewModels bool属性转换为适合列属性的正确可见性值。
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
</Window.Resources>
将复选框绑定到控制列可见性的ViewModel属性。
<CheckBox
x:Name="DetailsVisible"
Content="Show Details"
IsChecked="{Binding Path=DisplayDetails}" />
然后将Visibility绑定到ViewModels的DisplayDetails属性。请注意,绑定的是列自己的DataContext。
<DataGridTextColumn
Header="Reliability"
Binding="{Binding Path=Reliability}"
Visibility="{Binding (FrameworkElement.DataContext).DisplayDetails,
RelativeSource={x:Static RelativeSource.Self},
Converter={StaticResource BoolToVisConverter}}">
</DataGridTextColumn>
将以下代码添加到您的项目中,这将允许捕获DataGrid的DataContext中的更改。
FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));
FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid),
new FrameworkPropertyMetadata
(null, FrameworkPropertyMetadataOptions.Inherits,
new PropertyChangedCallback(OnDataContextChanged)));
每当您的DataGrid的DataContext更改时,我们会使用新的DataContext更新所有附加的DataGridColumn。
public static void OnDataContextChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
DataGrid grid = d as DataGrid;
if (grid != null)
{
foreach (DataGridColumn col in grid.Columns)
{
col.SetValue(FrameworkElement.DataContextProperty, e.NewValue);
}
}
}
需要注意的一个陷阱是,如果你像这样将你的数据上下文添加到页面中:
<Window.DataContext>
<vm:WeaponListViewModel />
</Window.DataContext>
那么在你的DataGrid有任何列之前,上述函数将被调用!
我通过在窗口创建后在代码后台手动附加我的DataConext来解决了这个问题。