I have several columns in a DataGrid that I would like to be visible or hidden based on CheckBox for that column. I searched quite a bit beforehand and found a number of different answers but in each case they either didn't work or were targeting different circumstances.
If I understand correctly ElementName won't work because the Visual Tree isn't available. However I have tried setting the Source and RelativeSource without any luck. In its current state it simple returns the Error: Unresolved reference 'filterDuration'. The error stops the program from running.
Updated with Suggestions below and more information but still unresolved
Here is the Converter: (it never even steps into this)
[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;
}
}
Here is the 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>
Here is the DataGrid: (Extra Columns and attributes removed for brevity)
<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>
Your example works for me, you shouldn't let yourself get confused by the error in the designer, at runtime it works - x:Reference bindings seem to confuse the designer quite a bit.
Besides that, you have some minor errors in your value converter:
[ValueConversion(typeof(bool), typeof(Visibility))]
UPDATE
With your updated question you'll need a way to link the different contexts. If you can't do it by adding a property to your ViewModel you can still create a resource object. The other answer by Rohit Vats abuses a CheckBox as such a resource object. If you wanted a "cleaner" way just define a new DependencyObject subclass with a DependencyProperty for the checked state, then put an instance of that class into a static resource. This resource can then be used to have the controls communicate with each other.
Controls inside DataTemplate doesn't have same name scope and hence can't binded from controls outside it's name scope either via ElementName or x:Reference.
As a workaround you can achieve that by following way:
Code:
<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>
and in DataTemplate :
<CheckBox x:Name="filterDuration" Content="Duration"
IsChecked="{Binding IsChecked, Source={StaticResource DummyCheckBox}}"/>
Note - You can also declare the resource under window resources section in case it's not accessible from Dockpanel resources section in dataTemplate.
Obviously ideal solution would be to:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.