我正在尝试使用复选框控制列的可见性(这是在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属性转换为我们的列属性的正确Visibility值。
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
</Window.Resources>
将复选框绑定到ViewModels属性,该属性将控制列visibiity。
<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>
将以下代码添加到项目中,这样可以捕获DataGrids DataContext中的更改。
FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));
FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid),
new FrameworkPropertyMetadata
(null, FrameworkPropertyMetadataOptions.Inherits,
new PropertyChangedCallback(OnDataContextChanged)));
然后,只要更改了DataGrids DataContext,我们就会使用新的DataContext更新所有附加的DataGridColumsn。
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);
}
}
}
一个值得关注的问题。如果您将DataContext添加到页面中,如下所示:
<Window.DataContext>
<vm:WeaponListViewModel />
</Window.DataContext>
然后在DataGrid有任何列之前调用上面的函数!
我通过在创建窗口后手动将我的DataConext附加到代码中来解决这个问题。
答案 0 :(得分:3)
问题是DataGrid列不是可视树的一部分,因此它们不能使用绑定。 (“Binding”属性实际上是Binding类型的普通属性,而不是依赖属性。它将该绑定对象应用于单元格,这些单元格是可视树的一部分。)
以下是指向具有变通方法的博客的链接,并演示如何将列的可见性绑定到复选框:http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx
答案 1 :(得分:2)
使用x:Name
,x:Reference
和Source
的IMO更简单:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<CheckBox x:Name="showImperial" Content="Show Details" />
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="TOV (Bls)"
Width="80"
Binding="{Binding TOVBarrels}"
Visibility="{Binding Source={x:Reference showImperial},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}"/>
</DataGrid.Columns>
</DataGrid>