1

I want to disable visibility(collapse) of certain rows when a checkbox is checked and the bound data that is on that row matches certain criteria. for example(pseudo code):

    If(IsHideEnabledChecked && Row.Data.Enabled)
       Row.Visibility = Collapsed

I have created the datagrid(s) pro-grammatically due to the nature of the project i am working on, the number of datagrids need to match the number of objects in my collection. Normally in a non wpf world you would loop through the grids and change the row on condition:

public void HideEnabled(object sender, RoutedEventArgs)
   Foreach(DataGrid grid in DataGrids)
   {
     Foreach(DataGridRow row in grid)
     {
       if(row[0].Value == True)
           row.Visibile = false
     }
   }

My question is, how do i hide the rows after the checkbox is selected? and how would this be checked against the values on the current row? Can this all be done in c#? I have looked around and can see that dataTriggers can be used to bind a control to a column and datatype but that would not include checking against the bound data(the property "enabled")

Any help would be much appreciated :)

user2311703
  • 23
  • 1
  • 6
  • I would go for adding a data trigger on the rows, Bind the data trigger to the checkbox, when the checkbox is True, you would use the setter-Property to hide/collapse – JohnChris Feb 03 '17 at 09:48
  • How would adding data triggers on the rows be done in code? Im creating multiple datagrids in a collection rather than XAML Also, Once the checkbox is true, i need to only hide the rows that have the binding property (enabled == true) can this be done in the setter property? – user2311703 Feb 03 '17 at 09:57
  • WPF almost requires an MVVM approach which is code for Data Models and View Models and almost no code for view elements it should be pure Xaml where possible, so your View model says you have 10 data items you view would say Bind to all data items then format them as described in this template and use these bindings to show data – MikeT Feb 03 '17 at 10:28

2 Answers2

1

You should bind the control you want to hide to the checkbox.IsChecked this will then give you a boolean to visibility binding that you can convert with BooleanToVisibilityConverter i would suggest using a DataTemplate and a Collection Binding rather than code but you can do this in code as well

<UserControl.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</UserControl.Resources>
<Checkbox x:Name="hider" />
<Control Visibility="{Binding IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=hider}" />

or you can create your own converter that will handle Multiple Values if you want to combine the checkbox with another value see MultiValueConverter

public class MultiBooleanToVisibilityConverter : IMultiValueConverter
{

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.OfType<bool>().All(b => b == true))// your logic here
            return Visibility.Visible;
        else
            return Visibility.Collapsed;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new InvalidOperationException("One Way only");
    }
}

and then use

<Control.Visibility>
   <MultiBinding Converter="{StaticResource MultiBooleanToVisibilityConverter}">
        <Binding Path="IsChecked" ElementName="hider"/>
        <Binding Path="secondfield" />
    </MultiBinding>
</Control.Visibility>
MikeT
  • 5,398
  • 3
  • 27
  • 43
  • Its not a single control, It is a specific set of rows within a datagrid, and would be done in code within those specific datagrids, if that is any help – user2311703 Feb 03 '17 at 09:59
  • Thanks i will have a crack at this method :) – user2311703 Feb 03 '17 at 10:12
  • @user2311703 I slightly misread the question, so switched to a multivalue converter, however every control is a single control there are no limits on how many controls can be bound in a similar way – MikeT Feb 03 '17 at 10:13
0

You could handle the Checked event for the CheckBox and find its parent DataGridRow container in the visual tree using the following help method:

    private void CheckBox_Checked(object sender, RoutedEventArgs e)
    {
        CheckBox checkBox = sender as CheckBox;
        var dataObject = checkBox.DataContext as YourDataClass;
        if (dataObject.SomeProperty == true)
        {
            DataGridRow parentRow = FindParent<DataGridRow>(checkBox);
            if (parentRow != null)
                parentRow.Visibility = Visibility.Collapsed;
        }
    }

    private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
    {
        var parent = VisualTreeHelper.GetParent(dependencyObject);

        if (parent == null) return null;

        var parentT = parent as T;
        return parentT ?? FindParent<T>(parent);
    }

You just hook up the event handler for the Checked event as usual. Either in the XAML markup:

<CheckBox ... Checked="CheckBox_Checked" />

Or programmatically:

CheckBox chk = new CheckBox();
chk.Checked += CheckBox_Checked;
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Thanks for the input! How does this relate to the datagrid i have in memory? I cant see a reference to anything like it. in my attempt i had to alter the code slightly so that the dataobject could be checked conditionally: checkBox.DataContext = _viewModel.EndPointTables; var dataObject = checkBox.DataContext as Dictionary>; – user2311703 Feb 03 '17 at 13:22
  • You don't need a reference to the DataGrid. You only need a reference to the parent DataGridRow of the Checkbox provided that you want to hide the row on which the Checkbox is located. – mm8 Feb 03 '17 at 13:25
  • Sorry previous comment couldnt be edited: Thanks for the input! How does this relate to the datagrid i have in memory? I cant see a reference to anything like it. in my attempt i had to alter the code slightly so that the dataobject could be checked conditionally, the view model is actually a Dictionary where the list is what links to each data grid ( i generate multiple in the UI) I cant see a link to any grid at all? sorry if im being silly here, new to WPF ways of thinking – user2311703 Feb 03 '17 at 13:36
  • So this isnt a checkbox inside of the grid, it is a checkbox control that would change how all of the grids display – user2311703 Feb 03 '17 at 13:37
  • All rows of the DataGrid? Why don't you simply set the Visibility of the DataGrid itself to Collapsed then? What's the point of hiding all rows one by one...? – mm8 Feb 03 '17 at 14:40
  • correct yeah its a checkbox that hides certain rows @mm8, the requirement of the program is to "filter" the list as it would be too large to go through, Hiding rows so that they are able to see and change data on others. Unfortunately due to the nature of what this program will be used for, it wont be possible – user2311703 Feb 03 '17 at 14:58
  • You should probably rephrase your question and provide a better explanation of your issue because I don't understand your requirements. – mm8 Feb 03 '17 at 15:02