We all fased with problem when we need to hide column of DataGrid by some condition. There are at least two approaches to solve this problem. Bouth of approaches requires proxy element. I use bouth of these approaches. As you see, using of FreezableProxy
as proxy element does't require ContentControl
, but requires specify additional class (FreezableProxy
). Using of FrameworkElement
as proxy does't require specify additional class (like FreezableProxy
), but requires adding ContentControl
to markup.
XAML:
<Window.Resources>
<SampleRadioBoxCheckedConverter:FreezableProxy x:Key="FreezableProxy" Data="{Binding}"/>
<FrameworkElement x:Key="FrameworkElement" DataContext="{Binding}"/>
</Window.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<DataGrid AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name"/>
<DataGridTextColumn Header="Type"
Visibility="{Binding Data.IsPartnerColumnVisible, Source={StaticResource FreezableProxy}}"/>
<DataGridTextColumn Header="Number"
Visibility="{Binding DataContext.IsPartnerColumnVisible, Source={StaticResource FrameworkElement}}"/>
</DataGrid.Columns>
</DataGrid>
<ContentControl Grid.Row="1" Content="{StaticResource FrameworkElement}" Visibility="Collapsed"></ContentControl>
</Grid>
Code-behind:
public class FreezableProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new FreezableProxy();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object),
typeof(FreezableProxy));
}
public partial class MainWindow : INotifyPropertyChanged
{
private Visibility _isPartnerColumnVisible = Visibility.Hidden;
public Visibility IsPartnerColumnVisible
{
get
{
return _isPartnerColumnVisible;
}
set
{
_isPartnerColumnVisible = value;
RaisePropertyChanged("IsPartnerColumnVisible");
}
}
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(String prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
}
Bouth approaches look very similiar. Suggest we use second approach (using FrameworkElement
). Then I have a question - why I need to specify additional ContentControl
if Binding
actually set to {StaticResource FrameworkElement}
? What a magic is ContentControl
doing? When we use FrezableProxy
we need not specify any ContentControl-s
or something else and it works fine.
UPDATE
<FrameworkElement x:Key="FrameworkElement" DataContext="{Binding}"/>
/////<ContentControl Grid.Row="1" Content="{StaticResource FrameworkElement}" Visibility="Collapsed"></ContentControl>
Why this doesn't work? ContentControl is commented but I set DataContext
property of FrameworkElement
explicitly.