Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Refactoring DataGridAssist mouse handling
Rather than handling the tunneling event and "pre-processing", it now handles the (already handled - by the cell) bubbling event to perform additional actions.
  • Loading branch information
nicolaihenriksen authored and Keboo committed Aug 30, 2022
commit 94d023ee158fa8ad7c87df0e1c9e657e2b41d685
16 changes: 12 additions & 4 deletions MainDemo.Wpf/DataGrids.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,23 @@
</UserControl.Resources>

<StackPanel>
<TextBlock
Style="{StaticResource MaterialDesignHeadline5TextBlock}"
Text="Custom Columns"/>
<StackPanel Orientation="Horizontal">
<TextBlock
Style="{StaticResource MaterialDesignHeadline5TextBlock}"
Text="Custom Columns"/>
<TextBlock
Style="{StaticResource MaterialDesignBody1TextBlock}" VerticalAlignment="Center"
Margin="25,0,10,0"
Text="SelectionUnit:"/>
<ComboBox x:Name="selectionUnitComboBox" ItemsSource="{Binding SelectionUnits}" SelectedIndex="0" VerticalAlignment="Center" />
</StackPanel>

<smtx:XamlDisplay UniqueKey="grids_1">
<DataGrid
ItemsSource="{Binding Items1}"
CanUserAddRows="False" AutoGenerateColumns="False"
HeadersVisibility="All">
HeadersVisibility="All"
SelectionUnit="{Binding ElementName=selectionUnitComboBox, Path=SelectedValue}">
<DataGrid.Resources>
<domain:BindingProxy
x:Key="DataContextProxy"
Expand Down
3 changes: 2 additions & 1 deletion MainDemo.Wpf/Domain/ListsAndGridsViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -89,5 +89,6 @@ private static ObservableCollection<SelectableViewModel> CreateData()

public IList<string> Files { get; }

public IEnumerable<DataGridSelectionUnit> SelectionUnits => new[] { DataGridSelectionUnit.FullRow, DataGridSelectionUnit.Cell, DataGridSelectionUnit.CellOrRowHeader };
}
}
117 changes: 64 additions & 53 deletions MaterialDesignThemes.Wpf/DataGridAssist.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,20 @@ private static void EnableEditBoxAssistPropertyChangedCallback(DependencyObject

if (enableCheckBoxAssist)
{
dataGrid.PreviewMouseLeftButtonDown += AllowDirectEditWithoutFocus;
dataGrid.KeyDown += EditOnSpacebarPress;
// Register for bubbling events from cells, even when the cell handles them (thus the 'true' parameter)
dataGrid.AddHandler(UIElement.MouseLeftButtonDownEvent, (RoutedEventHandler)OnMouseLeftButtonDown, true);
dataGrid.PreviewKeyDown += EditOnSpacebarPress;
}
else
{
dataGrid.PreviewMouseLeftButtonDown -= AllowDirectEditWithoutFocus;
dataGrid.KeyDown -= EditOnSpacebarPress;
dataGrid.RemoveHandler(UIElement.MouseLeftButtonDownEvent, (RoutedEventHandler)OnMouseLeftButtonDown);
dataGrid.PreviewKeyDown -= EditOnSpacebarPress;
}
}

// This relay is only needed because the UIElement.AddHandler() has strict requirements for the signature of the passed Delegate
private static void OnMouseLeftButtonDown(object sender, RoutedEventArgs e) => AllowDirectEditWithoutFocus(sender, (MouseButtonEventArgs)e);

#endregion

#region AttachedProperty : CornerRadiusProperty
Expand All @@ -201,11 +206,14 @@ public static void SetCornerRadius(DataGrid element, CornerRadius value)
private static void EditOnSpacebarPress(object sender, KeyEventArgs e)
{
var dataGrid = (DataGrid)sender;

if (e.Key == Key.Space && e.OriginalSource is DataGridCell cell
&& !cell.IsReadOnly && cell.Column is DataGridComboBoxColumn)
if (e.Key == Key.Space && e.OriginalSource is DataGridCell { IsReadOnly: false } cell)
{
dataGrid.BeginEdit();
if (cell.Column is DataGridComboBoxColumn ||
cell.Column is System.Windows.Controls.DataGridTextColumn)
{
dataGrid.BeginEdit();
e.Handled = true;
}
}
}

Expand All @@ -227,67 +235,70 @@ private static void AllowDirectEditWithoutFocus(object sender, MouseButtonEventA
return;
}

if (dataGridCell?.Content is UIElement element)
if (dataGridCell.Content is UIElement element)
{
var dataGrid = (DataGrid)sender;

// Check if the cursor actually hit the element and not just the cell
var mousePosition = mouseArgs.GetPosition(element);
var elementHitBox = new Rect(element.RenderSize);
if (elementHitBox.Contains(mousePosition))
// If it is a DataGridTemplateColumn we want the
// click to be handled naturally by the control
if (dataGridCell.Column.GetType() == typeof(DataGridTemplateColumn))
{
return;
}
if (dataGridCell.IsEditing)
{
// If the cell is already being edited, we don't want to (re)start editing
return;
}

dataGrid.CurrentCell = new DataGridCellInfo(dataGridCell);
dataGrid.BeginEdit();

switch (dataGridCell.Content)
{
// If it is a DataGridTemplateColumn we want the
// click to be handled naturally by the control
if (dataGridCell.Column.GetType() == typeof(DataGridTemplateColumn))
case TextBox textBox:
{
return;
// Send a 'left-click' routed event to the TextBox to place the I-beam at the position of the mouse cursor
var mouseDownEvent = new MouseButtonEventArgs(mouseArgs.MouseDevice, mouseArgs.Timestamp, mouseArgs.ChangedButton)
{
RoutedEvent = Mouse.MouseDownEvent,
Source = mouseArgs.Source
};
textBox.RaiseEvent(mouseDownEvent);
break;
}
if (dataGridCell.IsEditing)
{
// If the cell is already being edited, we let the cell itself handle the mouse event
return;
}

dataGrid.CurrentCell = new DataGridCellInfo(dataGridCell);
dataGrid.BeginEdit();
//Begin edit likely changes the visual tree, trigger the mouse down event to cause the DataGrid to adjust selection
var mouseDownEvent = new MouseButtonEventArgs(mouseArgs.MouseDevice, mouseArgs.Timestamp, mouseArgs.ChangedButton)
case ToggleButton toggleButton:
{
RoutedEvent = Mouse.MouseDownEvent,
Source = mouseArgs.Source
};
// Check if the cursor actually hit the checkbox and not just the cell
var mousePosition = mouseArgs.GetPosition(element);
var elementHitBox = new Rect(element.RenderSize);
if (elementHitBox.Contains(mousePosition))
{
// Send a 'left click' routed command to the toggleButton to toggle the state
var newMouseEvent = new MouseButtonEventArgs(mouseArgs.MouseDevice, 0, MouseButton.Left)
{
RoutedEvent = Mouse.MouseDownEvent,
Source = dataGrid
};

dataGridCell.RaiseEvent(mouseDownEvent);
toggleButton.RaiseEvent(newMouseEvent);
}
break;
}

switch (dataGridCell?.Content)
// Open the dropdown explicitly. Left clicking is not
// viable, as it would edit the text and not open the
// dropdown
case ComboBox comboBox:
{
// Send a 'left click' routed command to the toggleButton
case ToggleButton toggleButton:
{
var newMouseEvent = new MouseButtonEventArgs(mouseArgs.MouseDevice, 0, MouseButton.Left)
{
RoutedEvent = Mouse.MouseDownEvent,
Source = dataGrid
};

toggleButton.RaiseEvent(newMouseEvent);
break;
}

// Open the dropdown explicitly. Left clicking is not
// viable, as it would edit the text and not open the
// dropdown
case ComboBox comboBox:
{
comboBox.IsDropDownOpen = true;
mouseArgs.Handled = true;
break;
}

default:
{
break;
}
comboBox.IsDropDownOpen = true;
break;
}
}
}
Expand Down