Skip to content

Commit 5ab0773

Browse files
committed
Add new DataGridHelper with EnableCellEditAssist attached property which enabled direct editing for CheckBox and ComboBox cells. (default to false)
1 parent 4c5a4ed commit 5ab0773

File tree

5 files changed

+177
-10
lines changed

5 files changed

+177
-10
lines changed

docs/release-notes/1.5.0.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
- Fix WindowCommands tab stop bug [#2858](https://github.com/MahApps/MahApps.Metro/pull/2858) [@neilt6](https://github.com/neilt6)
2323
- Don't overwrite cancellation for window close event [#2868](https://github.com/MahApps/MahApps.Metro/pull/2868) [@batzen](https://github.com/batzen)
2424
- Expose close button margin for `MetroTabItem` [#2803](https://github.com/MahApps/MahApps.Metro/pull/2803)
25-
- New `Badged` control. Thx to @ButchersBoy
25+
- New `Badged` control. Thx to [@ButchersBoy](https://github.com/ButchersBoy)
2626
![image](https://cloud.githubusercontent.com/assets/658431/23340345/d7dc4c86-fc34-11e6-838b-1ebee9381c7d.png)
2727
- The `ControlsHelper.CornerRadius` can now used for `SplitButton` and `DropDownButton`.
2828
- New underline types for `TabControl` and `MetroTabControl` [#2902](https://github.com/MahApps/MahApps.Metro/pull/2902)
@@ -69,6 +69,7 @@
6969
- Fix `SelectionChanged` event of `SplitButton` which fires now only once.
7070
- Add `TransitionCompleted` event to `MetroContentControl` and `WindowTransitionCompleted` event to `MetroWindow` which will be fired after the loaded Storyboard is completed.
7171
- Add new `WatermarkAlignment` attached property to `TextBoxHelper` which indicates the horizontal alignment of the watermark (incl. floating watermark).
72+
- Add new `DataGridHelper` with `EnableCellEditAssist` attached property which enabled direct editing for CheckBox and ComboBox cells. (default to false) Thx to [@ButchersBoy](https://github.com/ButchersBoy) (taken from [MaterialDesignInXamlToolkit](https://github.com/ButchersBoy/MaterialDesignInXamlToolkit))
7273
7374
## Closed Issues
7475

src/MahApps.Metro.Samples/MahApps.Metro.Core.Demo.Shared/Models/Album.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,19 @@ public int ArtistId
5252
}
5353
}
5454

55+
private bool isSelected;
56+
57+
public bool IsSelected
58+
{
59+
get { return this.isSelected; }
60+
set
61+
{
62+
if (value == this.isSelected) return;
63+
this.isSelected = value;
64+
this.OnPropertyChanged();
65+
}
66+
}
67+
5568
public string Title
5669
{
5770
get { return _title; }

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

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
<RowDefinition Height="Auto" />
4646
<RowDefinition Height="Auto" />
4747
<RowDefinition Height="Auto" />
48+
<RowDefinition Height="Auto" />
4849
</Grid.RowDefinitions>
4950

5051
<TextBlock Grid.Row="0"
@@ -60,50 +61,62 @@
6061
IsChecked="{Binding IsEnabled}" />
6162

6263
<TextBlock Grid.Row="1"
64+
Grid.Column="0"
65+
Margin="2"
66+
VerticalAlignment="Center"
67+
Text="CellEditAssist" />
68+
<CheckBox Grid.Row="1"
69+
Grid.Column="1"
70+
Margin="2"
71+
HorizontalAlignment="Left"
72+
VerticalAlignment="Center"
73+
IsChecked="{Binding Path=(controls:DataGridHelper.EnableCellEditAssist)}" />
74+
75+
<TextBlock Grid.Row="2"
6376
Grid.Column="0"
6477
Margin="2"
6578
VerticalAlignment="Center"
6679
Text="SelectionUnit" />
67-
<ComboBox Grid.Row="1"
80+
<ComboBox Grid.Row="2"
6881
Grid.Column="1"
6982
Width="100"
7083
Margin="2"
7184
VerticalAlignment="Center"
7285
ItemsSource="{StaticResource DataGridSelectionUnitArray}"
7386
SelectedValue="{Binding SelectionUnit}" />
7487

75-
<TextBlock Grid.Row="2"
88+
<TextBlock Grid.Row="3"
7689
Grid.Column="0"
7790
Margin="2"
7891
VerticalAlignment="Center"
7992
Text="GridLines" />
80-
<ComboBox Grid.Row="2"
93+
<ComboBox Grid.Row="3"
8194
Grid.Column="1"
8295
Width="100"
8396
Margin="2"
8497
VerticalAlignment="Center"
8598
ItemsSource="{StaticResource DataGridGridLinesVisibilityArray}"
8699
SelectedValue="{Binding GridLinesVisibility}" />
87100

88-
<TextBlock Grid.Row="3"
101+
<TextBlock Grid.Row="4"
89102
Grid.Column="0"
90103
Margin="2"
91104
VerticalAlignment="Center"
92105
Text="Headers" />
93-
<ComboBox Grid.Row="3"
106+
<ComboBox Grid.Row="4"
94107
Grid.Column="1"
95108
Width="100"
96109
Margin="2"
97110
VerticalAlignment="Center"
98111
ItemsSource="{StaticResource DataGridHeadersVisibilityArray}"
99112
SelectedValue="{Binding HeadersVisibility}" />
100113

101-
<TextBlock Grid.Row="4"
114+
<TextBlock Grid.Row="5"
102115
Grid.Column="0"
103116
Margin="2"
104117
VerticalAlignment="Center"
105118
Text="RowHeaderWidth" />
106-
<controls:NumericUpDown Grid.Row="4"
119+
<controls:NumericUpDown Grid.Row="5"
107120
Grid.Column="1"
108121
Width="100"
109122
Margin="2"
@@ -155,7 +168,11 @@
155168
<DataGridCheckBoxColumn Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Path=IsSelected, Mode=OneWay}"
156169
EditingElementStyle="{DynamicResource MetroDataGridCheckBox}"
157170
ElementStyle="{DynamicResource MetroDataGridCheckBox}"
158-
Header="IsSelected" />
171+
Header="Row Selected" />
172+
<DataGridCheckBoxColumn Binding="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
173+
EditingElementStyle="{DynamicResource MetroDataGridCheckBox}"
174+
ElementStyle="{DynamicResource MetroDataGridCheckBox}"
175+
Header="Album Selected" />
159176
<DataGridTextColumn Binding="{Binding Title}" Header="Title" />
160177
<DataGridTextColumn Binding="{Binding Artist.Name}" Header="Artist" />
161178
<DataGridTextColumn Binding="{Binding Genre.Name}" Header="Genre" />
@@ -174,7 +191,7 @@
174191
<Style.Triggers>
175192
<DataTrigger Binding="{Binding Price, Mode=OneWay, Converter={StaticResource AlbumPriceIsTooMuchConverter}}" Value="True">
176193
<Setter Property="Background" Value="#FF8B8B" />
177-
<Setter Property="Foreground" Value="Red" />
194+
<Setter Property="Foreground" Value="DarkRed" />
178195
</DataTrigger>
179196
<!-- IsMouseOver -->
180197
<MultiDataTrigger>
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Windows;
4+
using System.Windows.Controls;
5+
using System.Windows.Controls.Primitives;
6+
using System.Windows.Input;
7+
using System.Windows.Media;
8+
using System.Windows.Media.Media3D;
9+
10+
namespace MahApps.Metro.Controls
11+
{
12+
public static class DataGridHelper
13+
{
14+
private static DataGrid _suppressComboAutoDropDown;
15+
16+
public static readonly DependencyProperty EnableCellEditAssistProperty
17+
= DependencyProperty.RegisterAttached(
18+
"EnableCellEditAssist",
19+
typeof(bool),
20+
typeof(DataGridHelper),
21+
new PropertyMetadata(default(bool), EnableCellEditAssistPropertyChangedCallback));
22+
23+
/// <summary>
24+
/// Gets a value which indicates the preview cell editing is enabled or not.
25+
/// </summary>
26+
[Category(AppName.MahApps)]
27+
[AttachedPropertyBrowsableForType(typeof(DataGrid))]
28+
public static bool GetEnableCellEditAssist(DependencyObject element)
29+
{
30+
return (bool)element.GetValue(EnableCellEditAssistProperty);
31+
}
32+
33+
/// <summary>
34+
/// Sets a value which indicates the preview cell editing is enabled or not.
35+
/// </summary>
36+
[Category(AppName.MahApps)]
37+
[AttachedPropertyBrowsableForType(typeof(DataGrid))]
38+
public static void SetEnableCellEditAssist(DependencyObject element, bool value)
39+
{
40+
element.SetValue(EnableCellEditAssistProperty, value);
41+
}
42+
43+
private static void EnableCellEditAssistPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
44+
{
45+
var dataGrid = d as DataGrid;
46+
if (dataGrid == null)
47+
{
48+
return;
49+
}
50+
51+
dataGrid.PreviewMouseLeftButtonDown -= DataGridOnPreviewMouseLeftButtonDown;
52+
if ((bool)e.NewValue)
53+
{
54+
dataGrid.PreviewMouseLeftButtonDown += DataGridOnPreviewMouseLeftButtonDown;
55+
}
56+
}
57+
58+
private static void DataGridOnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
59+
{
60+
var dataGrid = (DataGrid)sender;
61+
62+
var inputHitTest = dataGrid.InputHitTest(e.GetPosition((DataGrid)sender)) as DependencyObject;
63+
64+
while (inputHitTest != null)
65+
{
66+
var dataGridCell = inputHitTest as DataGridCell;
67+
if (dataGridCell != null && dataGrid.Equals(dataGridCell.TryFindParent<DataGrid>()))
68+
{
69+
if (dataGridCell.IsReadOnly) return;
70+
71+
ToggleButton toggleButton;
72+
ComboBox comboBox;
73+
if (IsDirectHitOnEditComponent(dataGridCell, e, out toggleButton))
74+
{
75+
dataGrid.CurrentCell = new DataGridCellInfo(dataGridCell);
76+
dataGrid.BeginEdit();
77+
toggleButton.SetCurrentValue(ToggleButton.IsCheckedProperty, !toggleButton.IsChecked);
78+
dataGrid.CommitEdit();
79+
e.Handled = true;
80+
}
81+
else if (IsDirectHitOnEditComponent(dataGridCell, e, out comboBox))
82+
{
83+
if (_suppressComboAutoDropDown != null) return;
84+
85+
dataGrid.CurrentCell = new DataGridCellInfo(dataGridCell);
86+
dataGrid.BeginEdit();
87+
//check again, as we move to the edit template
88+
if (IsDirectHitOnEditComponent(dataGridCell, e, out comboBox))
89+
{
90+
_suppressComboAutoDropDown = dataGrid;
91+
comboBox.DropDownClosed += ComboBoxOnDropDownClosed;
92+
comboBox.IsDropDownOpen = true;
93+
}
94+
e.Handled = true;
95+
}
96+
97+
return;
98+
}
99+
100+
inputHitTest = (inputHitTest is Visual || inputHitTest is Visual3D)
101+
? VisualTreeHelper.GetParent(inputHitTest)
102+
: null;
103+
}
104+
}
105+
106+
private static void ComboBoxOnDropDownClosed(object sender, EventArgs eventArgs)
107+
{
108+
_suppressComboAutoDropDown.CommitEdit();
109+
_suppressComboAutoDropDown = null;
110+
((ComboBox)sender).DropDownClosed -= ComboBoxOnDropDownClosed;
111+
}
112+
113+
private static bool IsDirectHitOnEditComponent<TControl>(ContentControl contentControl, MouseEventArgs e, out TControl control)
114+
where TControl : Control
115+
{
116+
control = contentControl.Content as TControl;
117+
if (control == null)
118+
{
119+
return false;
120+
}
121+
122+
var frameworkElement = VisualTreeHelper.GetChild(contentControl, 0) as FrameworkElement;
123+
if (frameworkElement == null)
124+
{
125+
return false;
126+
}
127+
128+
var transformToAncestor = (MatrixTransform)control.TransformToAncestor(frameworkElement);
129+
var rect = new Rect(new Point(transformToAncestor.Value.OffsetX, transformToAncestor.Value.OffsetY),
130+
new Size(control.ActualWidth, control.ActualHeight));
131+
132+
return rect.Contains(e.GetPosition(frameworkElement));
133+
}
134+
}
135+
}

src/MahApps.Metro/MahApps.Metro.Shared/MahApps.Metro.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
<Compile Include="$(MSBuildThisFileDirectory)Controls\Helper\ComboBoxHelper.cs" />
7171
<Compile Include="$(MSBuildThisFileDirectory)Controls\Helper\ControlsHelper.cs" />
7272
<Compile Include="$(MSBuildThisFileDirectory)Controls\Helper\DataGridCellHelper.cs" />
73+
<Compile Include="$(MSBuildThisFileDirectory)Controls\Helper\DataGridHelper.cs" />
7374
<Compile Include="$(MSBuildThisFileDirectory)Controls\Helper\DataGridRowHelper.cs" />
7475
<Compile Include="$(MSBuildThisFileDirectory)Controls\Helper\ExpanderHelper.cs" />
7576
<Compile Include="$(MSBuildThisFileDirectory)Controls\Helper\GroupBoxHelper.cs" />

0 commit comments

Comments
 (0)