0

I am trying to setup and binding with a ToggleButton to change the visibility of columns in a DataGrid. I am following this post The issue being is that converter never fires and I don't know why.

My code is as follows:

<DataGridTemplateColumn Header="My Header" 
                        Visibility="{Binding IsChecked,
                                     ElementName=AdvancedToggleButton, 
                                     Converter={StaticResource booleanToVisaulConverter}}" >
<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
                <!-- Elements removed for brevity-->
        </StackPanel>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

The Converter is this

<Page.Resources>
    <local:BooleanToVisaulConverter x:Key="booleanToVisaulConverter" />
</Page.Resources>

With the code behind;

public class BooleanToVisaulConverter : IValueConverter
{
    public object Convert(object value, Type targetType,  object parameter, CultureInfo culture)
    {
        bool visibility = (bool)value;
        return visibility ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Visibility visibility = (Visibility)value;
        return (visibility == Visibility.Visible);
    }
}

edit: @Breeze found a mistake that booleanToVisaulConverter was not actually pointing to BooleanToVisaulConverter. This has been fixed but still not firing. Asked for the ToggleButton code;

<ToggleButton Name="AdvancedToggleButton" Content="Advanced" />
Community
  • 1
  • 1
Xaphann
  • 3,195
  • 10
  • 42
  • 70
  • 1
    Please share the declaration of advancedToggleButton if the error is not that you use BooleanToVisibiltyConverter in your static resource instead of BooleanToVisaulConverter – Breeze Nov 10 '15 at 17:18
  • @Breeze fixed the BooleanToVisaulConverter, see above – Xaphann Nov 10 '15 at 17:52
  • There's already a BooleanToVisibilityConverter in the framework, fyi. And you should use a tool like Snooper to inspect the visual tree for binding errors at runtime. –  Nov 10 '15 at 17:53
  • Found a workaround for you, very strange all points out that you can't show hide columns in a "non barbaric" manner ... or maybe I didn't find one. Will be back with some code in a minute. – kirotab Nov 10 '15 at 20:02

2 Answers2

4

I've run into the same problem a couple of weeks ago. My solution for this is the following:

At first you have to implement a binding-proxy-class which holds your datacontext. This class looks like:

public class BindingProxy : Freezable
{   
    public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
        "Data", typeof (object), typeof (BindingProxy), new UIPropertyMetadata(null));

    public object Data
    {
        get { return GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
}

Then you define Page-Resources you create an instance of this binding-proxy like:

<namespaceOfProxy:BindingProxy Data="{Binding}" x:Key="proxy"/>

Then you can bind the Visiblity of your DataGridTemplateColumn to a property in your viewmodel with the following code:

Visibility="{Binding Source={StaticResource proxy}, Path=Data.IsToggleButtonChecked, Converter={StaticResource booleanToVisaulConverter}}"

This works for binding the visibility to a property in your viewmodel. In your case I would bind the state of the also to a property in the viewmodel.

Tomtom
  • 9,087
  • 7
  • 52
  • 95
0

So it turns out that if you set Visibility to the header and the cells of the column it's still there and not completely hidden ... after some digging (never used data grid before :) ) I've found that you have access to the columns from the DataGrid object so the quickest thing to work is:

XAML

<ToggleButton Name="AdvancedToggleButton" 
              Content="Advanced"
              Click="AdvancedToggleButton_Click" />

The code behind

private void AdvancedToggleButton_Click(object sender, RoutedEventArgs e)
{
    var newVisibility = (bool)(sender as ToggleButton).IsChecked ?
        Visibility.Visible : Visibility.Collapsed;
    this.theDataGrid.Columns[0].Visibility = newVisibility;
}

Of course You'll have to implement some logic to get the appropriate column and not use fixed index if you're going to use it in real code.

kirotab
  • 1,296
  • 1
  • 11
  • 18