我在DataGrid中有几个列,我想基于CheckBox为该列显示或隐藏它们。我事先搜索了很多,发现了许多不同的答案,但在每种情况下,他们要么没有工作,要么针对不同的情况。
如果我理解正确,ElementName不会起作用,因为Visual Tree不可用。但是我试过设置Source和RelativeSource而没有任何运气。在当前状态下,它简单地返回错误:未解析的参考' filterDuration'。该错误会使程序停止运行。
更新了以下建议和更多信息,但仍未解决
这是转换器:(它甚至从未涉及到这一点)
[ValueConversion(typeof(bool), typeof(Visibility))]
public class FilterVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool isSelected = System.Convert.ToBoolean(value);
return isSelected ? Visibility.Visible : Visibility.Hidden;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var v = (Visibility)value;
return v == Visibility.Hidden ? false : true;
}
}
这是CheckBox:
<DataTemplate x:Key="Settings">
<DockPanel>
<GroupBox Header="Filter Columns" DockPanel.Dock="Right">
<ag:AutoGrid Columns="150, 150, 150" RowCount="7" RowHeight="20">
<CheckBox Content="Id" />
<CheckBox Content="Desc" />
<CheckBox x:Name="filterDuration" Content="Duration" />
</ag:AutoGrid>
</GroupBox>
</DockPanel>
</DataTemplate>
以下是DataGrid :(为简洁起见,删除了额外的列和属性)
<DockPanel Grid.Row="0" Grid.Column="0">
<Expander DockPanel.Dock="Top" Header="{x:Static p:Resources.shSettings}" ContentTemplate="{StaticResource Settings}" IsExpanded="True" />
<Border DockPanel.Dock="Top" Background="#FF595959">
<TextBlock Text="{x:Static p:Resources.shViolations}" Style="{StaticResource SectionHeaderText}" />
</Border>
<DataGrid IsReadOnly="True" ItemsSource="{Binding items}" SelectedItem="{Binding Path=selecteditem}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="Duration" Binding="{Binding Duration}" Visibility="{Binding Source={x:Reference filterDuration}, Path=IsChecked, Converter={StaticResource FilterVisibility}}" />
<DataGridTextColumn Header="CTG Id" Binding="{Binding Id}" />
</DataGrid.Columns>
</DataGrid>
</DockPanel>
答案 0 :(得分:2)
你的例子对我有用,你不应该让自己对设计师的错误感到困惑,在运行时它可以工作 - x:参考绑定似乎让设计师有点混淆。
除此之外,您的值转换器中存在一些小错误:
[ValueConversion(typeof(bool), typeof(Visibility))]
<强>更新强>
根据您更新的问题,您需要一种方法来链接不同的上下文。如果您无法通过向ViewModel添加属性来执行此操作,则仍可以创建资源对象。 Rohit Vats的另一个答案是将CheckBox滥用为这样的资源对象。如果您想要一种“更干净”的方式,只需为已检查状态定义一个带有DependencyProperty的新DependencyObject子类,然后将该类的实例放入静态资源中。然后可以使用此资源使控件相互通信。
答案 1 :(得分:1)
DataTemplate内部的控件没有相同的名称范围,因此无法通过ElementName或x:Reference来绑定名称范围之外的控件。
作为一种解决方法,您可以通过以下方式实现这一目标:
代码:
<DockPanel .....>
<DockPanel.Resources>
<CheckBox x:Key="DummyCheckBox"/>
</DockPanel.Resources>
.........
<DataGridTextColumn Header="Duration" Binding="{Binding Duration}"
Visibility="{Binding Source={StaticResource DummyCheckBox},
Path=IsChecked, Converter={StaticResource FilterVisibility}}"/>
.........
</DockPanel>
和 DataTemplate :
<CheckBox x:Name="filterDuration" Content="Duration"
IsChecked="{Binding IsChecked, Source={StaticResource DummyCheckBox}}"/>
注意 - 如果无法从dataTemplate中的Dockpanel资源部分访问该资源,您也可以在窗口资源部分声明该资源。
显然,理想的解决方案是: