I have a subclass for DataGrid which supplies some additional functionality and modifies the default values for some of its properties. One thing in particular is I wanted the grid to be read-only by default, so I set IsReadOnly = true in its constructor.
Recently, I ran into an issue whereby using the grid in a template caused it to be read-only regardless how IsReadOnly was set in the template. Looking at the dependency property precedence page, I reached the conclusion that overriding metadata for IsReadOnlyProperty was the correct way to change its default:
IsReadOnlyProperty.OverrideMetadata(typeof(NewDataGrid), new FrameworkPropertyMetadata(true));
While this resolved the issue with control templates, it appears to break mouse double-click command bindings:
<DataGrid.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}"/>
</DataGrid.InputBindings>
Is there a better way to change IsReadOnly's default value without either breaking mouse bindings and/or templates?
Clarification about the command:
DoubleClickCommand itself is a RoutedUICommand defined in resources like so:
<RoutedUICommand x:Key="DoubleClickCommand"/>
Out of habit, I typically place this in the parent Window or UserControl's resource dictionary, but I can move it to the grid's resources as well without any change in behavior.
The command is then attached to the grid's command bindings:
<DataGrid.CommandBindings>
<CommandBinding Command="{StaticResource DoubleClickCommand}" Executed="DoubleClick_Executed" CanExecute="DoubleClick_CanExecute"/>
</DataGrid.CommandBindings>
I doubt that your issue is related to overriding the default value of the
DataGrid.IsReadOnlyproperty. There is no logical relation between a read-onlyDataGridand mouse input events.Instead it looks like the mouse events are handled by the internal elements of the
DataGridlikeDataGridCell- independent of the control's read-only state. For example double clicking the background of theDataGridwill work as expected, whereas clicking on a cell (or the content of a cell) won't.To fix it, I suggest to override the control's
Control.OnMouseDoubleClickand/orControl.OnPreviewMouseDoubleClickmethods.This should be generally your first approach before registering event handlers. First override the virtual members of the customized or extended control. It will give you greater control and your code looks cleaner too.
This is because the overrides are always invoked even if the override is a virtual event invocator (for example
Control.OnPreviewMouseDoubleClick) and the control decides to not raise the public associated event.So, instead of registering a mouse gesture, override the inherited event invocators:
This is not related to the recommended fix, but a general recommendation in regards to your original implementation: the way you set the
MouseBinding.Commandusing theStaticResourcemarkup extension looks odd. The command should be aRoutedCommandthat is usually defined asstaticand referenced in XAML using thex:Staticextension: