WPF Visibility Binding Column in a DataGrid

749 Views Asked by At

I have a DataGrid where I am trying to control the visibility of each column. Everything works fine when I bind the source of the column to the actual ViewModel, but I've read that the column should be bound to a Framework Element, which I am not fully understanding (because it doesn't work).

I have bound each column differently. One directly to the ViewModel, which works. The other column I bound to the FrameworkElement, which does not work. I have copied this example from a much larger block of code, but I think I got everything relevant.

Could someone please show me how it should be done. Any explanation to help me understand would also be appreciated.

<Page x:Class="gobo2018.View.TestPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:gobo2018.View"
      xmlns:ViewModel="clr-namespace:gobo2018.ViewModel"

      Title="TestPage">

    <Page.Resources>
        <ViewModel:ActiveJobViewModel x:Key="ActiveJobViewModel"/>

        <Style TargetType="{x:Type TextBlock}" x:Key="WrapText">
            <Setter Property="TextWrapping" Value="Wrap"/>
        </Style>
    </Page.Resources>

    <Grid Grid.Row="9" HorizontalAlignment="Stretch" DataContext="{Binding Mode=OneWay, Source={StaticResource ActiveJobViewModel}}"  >
        <Grid.Resources>
            <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
        </Grid.Resources>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="0"/>
            <RowDefinition MaxHeight="610"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"/>
        </Grid.ColumnDefinitions>


        <StackPanel Grid.Row="0" Orientation="Vertical" Style="{StaticResource GlobalStackPanelStyle}">

            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Background="Black">

                <CheckBox VerticalAlignment="Center" IsChecked="{Binding EditVisibility, UpdateSourceTrigger=PropertyChanged}" IsTabStop="False" Margin=" 3 0 0 0 "/>
                <Label Content="Edit/Delete" Margin=" 0 0 13 0 "  HorizontalAlignment="Right" VerticalAlignment="Center"/>

                <CheckBox VerticalAlignment="Center" IsChecked="{Binding DateVisibility, UpdateSourceTrigger=PropertyChanged}" IsTabStop="False" Margin=" 3 0 0 0 "/>
                <Label Content="Date" Margin=" 0 0 13 0 "  HorizontalAlignment="Right" VerticalAlignment="Center"/>

            </StackPanel>
        </StackPanel>



        <DataGrid Grid.Row="2" x:Name="EstimateGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" 
                              RowDetailsVisibilityMode="VisibleWhenSelected"  MaxHeight="600" Width="Auto" HorizontalAlignment="Left"
                              SelectionUnit="FullRow"  
                              SelectionMode="Single" 
                              ItemsSource="{Binding EstimateSortView, UpdateSourceTrigger=PropertyChanged}"
                              CanUserAddRows="False"
                              IsReadOnly="True"
                              SelectedItem="{Binding EstimateSelectedItem}"
                              SelectedIndex="-1"
                              SelectedValue ="{Binding EstimateGridSelectedValue}">

            <DataGrid.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"  Color="Yellow"/>
            </DataGrid.Resources>


            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Edit" 
                                                    Visibility="{Binding EditVisibility, Converter={StaticResource booleanToVisibility}, UpdateSourceTrigger=PropertyChanged, Source={StaticResource ProxyElement}}">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>

                            <Button Content="Edit Row" Foreground="DarkRed" FontSize="10" VerticalAlignment="Center" Padding="3"
                                                Command="{Binding Path=DataContext.ShowEstimatingUserControlCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" 
                                                CommandParameter="Edit"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn Header="Delete"
                                                    Visibility="{Binding EditVisibility, Converter={StaticResource booleanToVisibility}, UpdateSourceTrigger=PropertyChanged, Source={StaticResource ActiveJobViewModel}}">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>

                            <Button Content="Delete" Foreground="DarkRed" FontSize="10"  VerticalAlignment="Center" Padding="3"
                                                Command="{Binding Path=DataContext.EstimateWindowDeleteDatagridRowCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" 
                                                CommandParameter="Delete"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>


            </DataGrid.Columns>
        </DataGrid>

    </Grid>
</Page>
1

There are 1 best solutions below

0
cuongtd On

Since Visibility wasn't DependencyProperty it could not binding.So instead of using default Visibility create a new Attached Property

public class VisibilityAttachedProperty
{
    public static bool GetVisibility(DependencyObject obj)
    {
        return (bool)obj.GetValue(VisibilityProperty);
    }
    public static void SetVisibility(DependencyObject obj, bool value)
    {
        obj.SetValue(VisibilityProperty, value);
    }
    public static readonly DependencyProperty VisibilityProperty =
    DependencyProperty.RegisterAttached("Visibility", typeof(bool), typeof(VisibilityAttachedProperty), new PropertyMetadata(true, OnVisibilityChanged));
    private static void OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            (d as DataGridColumn).Visibility = Visibility.Visible;
        }
        else
        {
            (d as DataGridColumn).Visibility = Visibility.Collapsed;
        }
    }
}

<DataGridTemplateColumn Header="Edit"  local:VisibilityAttachedProperty.Visibility="{Binding EditVisibility}">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>

                <Button Content="Edit Row" Foreground="DarkRed" FontSize="10" VerticalAlignment="Center" Padding="3"
                                                Command="{Binding Path=DataContext.ShowEstimatingUserControlCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" 
                                                CommandParameter="Edit"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>