views:

5588

answers:

1

Hello,

Is it possible to have a bound DataGridCheckBoxColumn call a method of click? Or event a row level or row enter event?

I'm trying to implement a datagrid that updates the underlying filtered ObservableCollection collection (great sameple here http://petermcg.wordpress.com/2009/01/29/filtering-silverlight-datagrid-rows/)

The filtering works fine if I press an update button or another outside method. But, I can't seem to find any internal grid event or anything on the DataGridCheckBoxColumn that will allow for me to call the update filter logic.

Any suggestions on how to implement a datagrid that updates the underlying collection on press of a checkbox?

Please find below my Xaml, it really isn't anything special.

+2  A: 

The DataGridCheckBoxColumn Type does not currently provide a Click event, in fact it doesn't currently provide any events. A cell rendered in a column of this Type just implements a TwoWay binding between the IsChecked property of a CheckBox control and the property (specified in the Binding) on the instance of T in the current row of the ObservableCollection<T> that the DataGrid is bound to.

You don't provide your Xaml so I'll use the example from my blog post referenced in your question. The workaround involves specifying a DataGridTemplateColumn containing a CheckBox and defining the Click event as follows:

<data:DataGrid x:Name="FilteredPeople" AutoGenerateColumns="False">
  <data:DataGrid.Columns>
    <data:DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" />
    <data:DataGridTextColumn Header="Age" Binding="{Binding Age}" />
    <data:DataGridCheckBoxColumn Header="Visible" Binding="{Binding IsVisible}" />

    <data:DataGridTemplateColumn Header="Row Filter">
      <data:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <CheckBox x:Name="RowFilterButton" IsChecked="{Binding IsVisible}"
                Content="Filter" Tag="{Binding}" Click="RowFilterButton_Click" />
        </DataTemplate>
      </data:DataGridTemplateColumn.CellTemplate>
    </data:DataGridTemplateColumn>

  </data:DataGrid.Columns>
</data:DataGrid>

An alternative to a CheckBox in this case could be a ToggleButton or normal Button control. Notice the binding for the Tag property of the CheckBox. This helps to find out in which row the CheckBox was clicked from code-behind:

private void RowFilterButton_Click(object sender, RoutedEventArgs e)
{
    Person person = ((CheckBox)sender).Tag as Person;
}

You can then remove this person from the ObservableCollection<T> or change it's properties to filter or update the DataGrid as appropriate.

That's normally where this answer would end but if you do not have this update installed there is a bug in the default SDK version of the Silverlight 2 DataGrid that prevents this. In this case the bug will manifest itself by the DataGrid not drawing the row the CheckBox is in (instead what you get looks like an invisible row) if you cause the DataGrid to be filtered when you click that CheckBox (i.e. the Checkbox has focus).

To avoid this bug, install the update or initiate any manipulation of the ObservableCollection<T> the DataGrid is bound to from a Control outside the DataGrid's rows as per this example.

Peter McGrattan
Thanks for your help. This is a much cleaner method then using the PreparingCellForEdit event since it doesn't require the user to double click. Thanks for your help.
Ben Bahrenburg
Just read your answer, Peter, and this Tag="{Binding}" trick just made my day, thanks!
Vinzz