Skip to content

Commit aabfdab

Browse files
committed
Merge branch 'jk/DataGridAssist-fixex-from-MDIX' into develop
2 parents 5ea3819 + cabfaec commit aabfdab

File tree

2 files changed

+85
-28
lines changed

2 files changed

+85
-28
lines changed

src/MahApps.Metro.Samples/MahApps.Metro.Demo/ExampleViews/DataGridExamples.xaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@
189189
RowHeaderWidth="20"
190190
SelectionUnit="FullRow"
191191
VirtualizingPanel.IsVirtualizingWhenGrouping="True">
192+
<mah:DataGridHelper.AutoGeneratedComboBoxColumnEditingStyle>
193+
<Style BasedOn="{StaticResource MahApps.Styles.ComboBox.DataGrid.Editing}" TargetType="{x:Type ComboBox}">
194+
<Setter Property="mah:TextBoxHelper.ClearTextButton" Value="True" />
195+
</Style>
196+
</mah:DataGridHelper.AutoGeneratedComboBoxColumnEditingStyle>
192197
<DataGrid.GroupStyle>
193198
<GroupStyle ContainerStyle="{StaticResource MahApps.Styles.GroupItem.DataGrid}">
194199
<GroupStyle.HeaderTemplate>

src/MahApps.Metro/Controls/Helper/DataGridHelper.cs

Lines changed: 80 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -511,20 +511,27 @@ private static void EnableCellEditAssistPropertyChangedCallback(DependencyObject
511511
{
512512
if (d is DataGrid dataGrid && e.OldValue != e.NewValue && e.NewValue is bool isEnabled)
513513
{
514-
dataGrid.PreviewMouseLeftButtonDown -= DataGridOnPreviewMouseLeftButtonDown;
514+
dataGrid.RemoveHandler(UIElement.MouseLeftButtonDownEvent, (RoutedEventHandler)DataGridOnMouseLeftButtonDown);
515+
dataGrid.PreviewKeyDown -= EditOnSpaceBarPress;
516+
515517
if (isEnabled)
516518
{
517-
dataGrid.PreviewMouseLeftButtonDown += DataGridOnPreviewMouseLeftButtonDown;
519+
// Register for bubbling events from cells, even when the cell handles them (thus the 'true' parameter)
520+
dataGrid.AddHandler(UIElement.MouseLeftButtonDownEvent, (RoutedEventHandler)DataGridOnMouseLeftButtonDown, true);
521+
dataGrid.PreviewKeyDown += EditOnSpaceBarPress;
518522
}
519523
}
520524
}
521525

526+
// This relay is only needed because the UIElement.AddHandler() has strict requirements for the signature of the passed Delegate
527+
private static void DataGridOnMouseLeftButtonDown(object sender, RoutedEventArgs e) => AllowDirectEditWithoutFocus(sender, (MouseButtonEventArgs)e);
528+
522529
/// <summary>
523530
/// Allows editing of components inside of a <see cref="DataGrid"/> cell with a single left click.
524531
/// </summary>
525-
private static void DataGridOnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
532+
private static void AllowDirectEditWithoutFocus(object sender, MouseButtonEventArgs mouseArgs)
526533
{
527-
var originalSource = (DependencyObject)e.OriginalSource;
534+
var originalSource = (DependencyObject)mouseArgs.OriginalSource;
528535
var dataGridCell = originalSource
529536
.GetVisualAncestry()
530537
.OfType<DataGridCell>()
@@ -541,49 +548,94 @@ private static void DataGridOnPreviewMouseLeftButtonDown(object sender, MouseBut
541548
{
542549
var dataGrid = (DataGrid)sender;
543550

544-
// Check if the cursor actually hit the element and not just the complete cell
545-
var mousePosition = e.GetPosition(element);
546-
var elementHitBox = new Rect(element.RenderSize);
547-
if (elementHitBox.Contains(mousePosition))
551+
// If it is a DataGridTemplateColumn we want the
552+
// click to be handled naturally by the control
553+
if (dataGridCell.Column.GetType() == typeof(DataGridTemplateColumn))
554+
{
555+
return;
556+
}
557+
558+
// If the cell is already being edited, we let the cell itself handle the mouse event
559+
if (dataGridCell.IsEditing)
560+
{
561+
return;
562+
}
563+
564+
// Don't handle events from nested data grids
565+
var parentDataGrid = dataGridCell
566+
.GetVisualAncestry()
567+
.OfType<DataGrid>()
568+
.FirstOrDefault();
569+
if (parentDataGrid != dataGrid)
548570
{
549-
// If it is a DataGridTemplateColumn we want the
550-
// click to be handled naturally by the control
551-
if (dataGridCell.Column.GetType() == typeof(DataGridTemplateColumn))
571+
return;
572+
}
573+
574+
dataGrid.CurrentCell = new DataGridCellInfo(dataGridCell);
575+
dataGrid.BeginEdit();
576+
577+
// Now use the content from the editable template/style
578+
switch (dataGridCell.Content)
579+
{
580+
case TextBoxBase textBox:
552581
{
553-
return;
554-
}
582+
if (TextBoxHelper.GetSelectAllOnFocus(textBox) == false)
583+
{
584+
// Send a 'left-click' routed event to the TextBox to place the I-beam at the position of the mouse cursor
585+
var mouseDownEvent = new MouseButtonEventArgs(mouseArgs.MouseDevice, mouseArgs.Timestamp, mouseArgs.ChangedButton)
586+
{
587+
RoutedEvent = Mouse.MouseDownEvent,
588+
Source = mouseArgs.Source
589+
};
590+
textBox.RaiseEvent(mouseDownEvent);
591+
}
555592

556-
dataGrid.CurrentCell = new DataGridCellInfo(dataGridCell);
557-
dataGrid.BeginEdit();
593+
break;
594+
}
558595

559-
// Now use the content from the editable template/style
560-
switch (dataGridCell.Content)
596+
case ToggleButton toggleButton:
561597
{
562-
// Send a 'left click' routed command to the toggleButton
563-
case ToggleButton toggleButton:
598+
// Check if the cursor actually hit the checkbox and not just the cell
599+
var mousePosition = mouseArgs.GetPosition(element);
600+
var elementHitBox = new Rect(element.RenderSize);
601+
if (elementHitBox.Contains(mousePosition))
564602
{
565-
var newMouseEvent = new MouseButtonEventArgs(e.MouseDevice, 0, MouseButton.Left)
603+
// Send a 'left click' routed command to the toggleButton to toggle the state
604+
var newMouseEvent = new MouseButtonEventArgs(mouseArgs.MouseDevice, mouseArgs.Timestamp, mouseArgs.ChangedButton)
566605
{
567606
RoutedEvent = Mouse.MouseDownEvent,
568607
Source = dataGrid
569608
};
570609

571610
toggleButton.RaiseEvent(newMouseEvent);
572-
break;
573611
}
574612

575-
// Open the dropdown explicitly. Left clicking is not viable, as it would edit the text and not open the dropdown
576-
case ComboBox comboBox:
577-
{
578-
comboBox.IsDropDownOpen = true;
579-
e.Handled = true;
580-
break;
581-
}
613+
break;
614+
}
615+
616+
// Open the dropdown explicitly. Left clicking is not viable, as it would edit the text and not open the dropdown
617+
case ComboBox comboBox:
618+
{
619+
comboBox.IsDropDownOpen = true;
620+
621+
break;
582622
}
583623
}
584624
}
585625
}
586626

627+
private static void EditOnSpaceBarPress(object sender, KeyEventArgs e)
628+
{
629+
if (sender is DataGrid dataGrid)
630+
{
631+
if (e is { Key: Key.Space, OriginalSource: DataGridCell { IsReadOnly: false, Column: DataGridComboBoxColumn } })
632+
{
633+
dataGrid.BeginEdit();
634+
e.Handled = true;
635+
}
636+
}
637+
}
638+
587639
public static readonly DependencyProperty SelectionUnitProperty
588640
= DependencyProperty.RegisterAttached(
589641
"SelectionUnit",

0 commit comments

Comments
 (0)