8

Hei,

I need help figuring out how to access checkbox in wpf datagrid header. Here's what i have:

<DataGrid.Columns>
    <DataGridTemplateColumn CanUserReorder="False" CanUserResize="False">
        <DataGridTemplateColumn.HeaderTemplate>
            <DataTemplate>
                <CheckBox Name="cbxAll" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" />
            </DataTemplate>
        </DataGridTemplateColumn.HeaderTemplate>
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <CheckBox IsChecked="{Binding Path=Checked, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding Path=NoErrors}" Name="theCheckbox" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

I have set the Name for the checkbox, but for some reason i cant access it from on the code side.

I need to access the checkbox to uncheck it after i refresh my datagrid items. How can i do this?

hs2d
  • 6,027
  • 24
  • 64
  • 103
  • 4
    You don't need to "Access" the checkbox. WPF is not winforms. [UI is not Data](http://stackoverflow.com/questions/14381402/wpf-programming-methodology/14382137#14382137). Bind the IsChecked property to a boolean value in the underlying DataContext. Learn MVVM. – Federico Berasategui Feb 06 '13 at 15:05
  • Also, if you look closely, the CheckBox is inside a `DataTemplate`, that means that there's NO actual CheckBox. It's just a template, so, while there's a way to inspect the visual tree and grab a reference to it at runtime, that's not the way to achieve what you want to achieve here. – Federico Berasategui Feb 06 '13 at 15:10
  • 1
    Seconding the learn MVVM. Almost impossible to do anything in WPF without first understanding it. – sircodesalot Feb 06 '13 at 15:11
  • 1
    Please notice that the checkbox what i need to change is in the datagrid header. How would binding IsChecked help me? Please give me a example? – hs2d Feb 06 '13 at 23:52

3 Answers3

9

A working example in MVVM:

ViewModel

public class MainWindowViewModel : INotifyPropertyChanged
{
    private bool allItemsAreChecked;

    public event PropertyChangedEventHandler PropertyChanged;

    public bool AllItemsAreChecked
    {
        get
        {
            return this.allItemsAreChecked;
        }
        set
        {
            this.allItemsAreChecked = value;
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs("AllItemsAreChecked"));
            }
        }
    }
}

XAML

<DataGridTemplateColumn CanUserReorder="False" CanUserResize="False">
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding
                RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
                Path=DataContext.AllItemsAreChecked}" />
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>
</DataGridTemplateColumn>
JoanComasFdz
  • 2,911
  • 5
  • 34
  • 50
  • 1
    This actually solved a lot of problems for me. e.g. I was able to resolve Select All checkbox functionality using this including its intermediate state. All you need to do is to set the value to boolean property as AllItemsAreChecked in your example. And I guess, this is the better and precise way of doing this rather than a hack at runtime. – Indigo Apr 25 '15 at 14:42
  • 2
    For current WPF versions, the binding should be updated to: **IsChecked="{Binding Path=DataContext.AllItemsAreChecked, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}, Mode=FindAncestor}}"** – Roger Spurrell Feb 17 '18 at 01:33
4

Allthough binding might be the way you should go, it is possible to do what you ask. Here's one way of doing it:

1.Give your header CheckBox an Uid

<CheckBox Uid="CheckAll" />

2.Name your DataGrid

<DataGrid Name="myDataGrid" />

3.Implement the following extension method

public static UIElement FindUid(this DependencyObject parent, string uid)
{
    var count = VisualTreeHelper.GetChildrenCount(parent);
    if (count == 0) return null;

    for (int i = 0; i < count; i++)
    {
        var el = VisualTreeHelper.GetChild(parent, i) as UIElement;
        if (el == null) continue;

        if (el.Uid == uid) return el;

        el = el.FindUid(uid);
        if (el != null) return el;
    }
    return null;
}

4.Access and uncheck the CheckBox in code behind like this

CheckBox checkBox = myDataGrid.FindUid("CheckAll") as CheckBox;
checkBox.IsChecked = false;
Eirik
  • 4,135
  • 27
  • 29
  • Thanks for working example! Better than just saying "Learn MVVM.". I know this method is not the best, but since nobody provided example how to bind the checkbox in header then this is my only option. Thanks again! – hs2d Feb 07 '13 at 09:48
0

Set one simple event:

<CheckBox x:Name="cbxAll" Click="cbxAll_Click"/>

In the event Click on the code:

private void cbxAll_Click(object sender, RoutedEventArgs e)
{
   var ckbox = sender as CheckBox;
   if (ckbox.IsChecked == true)
   {
    //Check all itens
   }
   else
   {
    //Uncheck all itens
   }
}

NOTE: The sender is checkbox

Darlan Dieterich
  • 2,369
  • 1
  • 27
  • 37