I am trying to create my own checkbox column (replacing the default one), in order to move to more complex data columns later-on, and I have the following code:
public class MyCheckBoxColumn : DataGridBoundColumn
{
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
var cb = new CheckBox();
var bb = this.Binding as Binding;
var b = new Binding { Path = bb.Path, Source = cell.DataContext };
cb.SetBinding(ToggleButton.IsCheckedProperty, b);
return cb;
}
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
var cb = new CheckBox();
var bb = this.Binding as Binding;
var b = new Binding { Path = bb.Path, Source = ToggleButton.IsCheckedProperty };
cb.SetBinding(ToggleButton.IsCheckedProperty, b);
return cb;
}
protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
{
var cb = editingElement as CheckBox;
return cb.IsChecked;
}
protected override void CancelCellEdit(FrameworkElement editingElement, object uneditedValue)
{
var cb = editingElement as CheckBox;
if (cb != null) cb.IsChecked = (bool)uneditedValue;
}
protected override bool CommitCellEdit(FrameworkElement editingElement)
{
var cb = editingElement as CheckBox;
BindingExpression binding = editingElement.GetBindingExpression(ToggleButton.IsCheckedProperty);
if (binding != null) binding.UpdateSource();
return true;// base.CommitCellEdit(editingElement);
}
}
And my custom DataGrid:
public class MyDataGrid : DataGrid
{
protected override void OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
{
try
{
var type = e.PropertyType;
if (type == typeof(bool))
{
var col = new MyCheckBoxColumn();
col.Binding = new Binding(e.PropertyName) {Mode = BindingMode.TwoWay};
e.Column = col;
}
else
{
base.OnAutoGeneratingColumn(e);
}
var propDescr = e.PropertyDescriptor as System.ComponentModel.PropertyDescriptor;
e.Column.Header = propDescr.Description;
}
catch (Exception ex)
{
Utils.ReportException(ex);
}
}
}
Now, everything seems nice except for two things:
- It seems that the only used method in in
MyCheckBoxColumn
is theGenerateElement()
. All the other methods are not used. I have put breakpoints in them and they never get hit... - I use an
ObservableCollection
as a data source and, while the rest of the columns notify me when they get changed, this one doesn't.
The odd thing is that the bool
value gets changed when you check/uncheck the checkbox, but without notification and without passing through CommitCellEdit()
.
Does anyone know what is going wrong here?
EDIT :
It seems that if I return a TextBlock
from inside GenerateElement()
it makes the other methods to be called (the notification problem doesn't get fixed though). But why doesn't this work with with CheckBoxes? How does the default check box column work???