33using System . Windows . Controls ;
44using System . Windows . Controls . Primitives ;
55using System . Windows . Data ;
6+ using System . Windows . Input ;
7+ using System . Windows . Media ;
8+ using System . Windows . Threading ;
69
710namespace MaterialDesignThemes . Wpf
811{
912 public static class DataGridAssist
1013 {
11- public static readonly DependencyProperty AutoGeneratedCheckBoxStyleProperty = DependencyProperty . RegisterAttached (
12- "AutoGeneratedCheckBoxStyle" , typeof ( Style ) , typeof ( DataGridAssist ) , new PropertyMetadata ( default ( Style ) , AutoGeneratedCheckBoxStylePropertyChangedCallback ) ) ;
14+ private static DataGrid _suppressComboAutoDropDown ;
1315
14- private static void AutoGeneratedCheckBoxStylePropertyChangedCallback ( DependencyObject dependencyObject , DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs )
16+ public static readonly DependencyProperty AutoGeneratedCheckBoxStyleProperty = DependencyProperty
17+ . RegisterAttached (
18+ "AutoGeneratedCheckBoxStyle" , typeof ( Style ) , typeof ( DataGridAssist ) ,
19+ new PropertyMetadata ( default ( Style ) , AutoGeneratedCheckBoxStylePropertyChangedCallback ) ) ;
20+
21+ private static void AutoGeneratedCheckBoxStylePropertyChangedCallback ( DependencyObject dependencyObject ,
22+ DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs )
1523 {
1624 ( ( DataGrid ) dependencyObject ) . AutoGeneratingColumn += ( sender , args ) =>
1725 {
1826 var dataGridCheckBoxColumn = args . Column as DataGridCheckBoxColumn ;
1927 if ( dataGridCheckBoxColumn == null ) return ;
2028
2129 dataGridCheckBoxColumn . ElementStyle = GetAutoGeneratedCheckBoxStyle ( dependencyObject ) ;
22- } ;
30+ } ;
2331 }
2432
2533 public static void SetAutoGeneratedCheckBoxStyle ( DependencyObject element , Style value )
@@ -32,12 +40,15 @@ public static Style GetAutoGeneratedCheckBoxStyle(DependencyObject element)
3240 return ( Style ) element . GetValue ( AutoGeneratedCheckBoxStyleProperty ) ;
3341 }
3442
35- public static readonly DependencyProperty AutoGeneratedEditingCheckBoxStyleProperty = DependencyProperty . RegisterAttached (
36- "AutoGeneratedEditingCheckBoxStyle" , typeof ( Style ) , typeof ( DataGridAssist ) , new PropertyMetadata ( default ( Style ) , AutoGeneratedEditingCheckBoxStylePropertyChangedCallback ) ) ;
43+ public static readonly DependencyProperty AutoGeneratedEditingCheckBoxStyleProperty = DependencyProperty
44+ . RegisterAttached (
45+ "AutoGeneratedEditingCheckBoxStyle" , typeof ( Style ) , typeof ( DataGridAssist ) ,
46+ new PropertyMetadata ( default ( Style ) , AutoGeneratedEditingCheckBoxStylePropertyChangedCallback ) ) ;
3747
38- private static void AutoGeneratedEditingCheckBoxStylePropertyChangedCallback ( DependencyObject dependencyObject , DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs )
48+ private static void AutoGeneratedEditingCheckBoxStylePropertyChangedCallback ( DependencyObject dependencyObject ,
49+ DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs )
3950 {
40- ( ( DataGrid ) dependencyObject ) . AutoGeneratingColumn += ( sender , args ) =>
51+ ( ( DataGrid ) dependencyObject ) . AutoGeneratingColumn += ( sender , args ) =>
4152 {
4253 var dataGridCheckBoxColumn = args . Column as DataGridCheckBoxColumn ;
4354 if ( dataGridCheckBoxColumn == null ) return ;
@@ -56,12 +67,15 @@ public static Style GetAutoGeneratedEditingCheckBoxStyle(DependencyObject elemen
5667 return ( Style ) element . GetValue ( AutoGeneratedEditingCheckBoxStyleProperty ) ;
5768 }
5869
59- public static readonly DependencyProperty AutoGeneratedEditingTextStyleProperty = DependencyProperty . RegisterAttached (
60- "AutoGeneratedEditingTextStyle" , typeof ( Style ) , typeof ( DataGridAssist ) , new PropertyMetadata ( default ( Style ) , AutoGeneratedEditingTextStylePropertyChangedCallback ) ) ;
70+ public static readonly DependencyProperty AutoGeneratedEditingTextStyleProperty = DependencyProperty
71+ . RegisterAttached (
72+ "AutoGeneratedEditingTextStyle" , typeof ( Style ) , typeof ( DataGridAssist ) ,
73+ new PropertyMetadata ( default ( Style ) , AutoGeneratedEditingTextStylePropertyChangedCallback ) ) ;
6174
62- private static void AutoGeneratedEditingTextStylePropertyChangedCallback ( DependencyObject dependencyObject , DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs )
75+ private static void AutoGeneratedEditingTextStylePropertyChangedCallback ( DependencyObject dependencyObject ,
76+ DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs )
6377 {
64- ( ( DataGrid ) dependencyObject ) . AutoGeneratingColumn += ( sender , args ) =>
78+ ( ( DataGrid ) dependencyObject ) . AutoGeneratingColumn += ( sender , args ) =>
6579 {
6680 var dataGridTextColumn = args . Column as DataGridTextColumn ;
6781 if ( dataGridTextColumn == null ) return ;
@@ -81,7 +95,8 @@ public static Style GetAutoGeneratedEditingTextStyle(DependencyObject element)
8195 }
8296
8397 public static readonly DependencyProperty CellPaddingProperty = DependencyProperty . RegisterAttached (
84- "CellPadding" , typeof ( Thickness ) , typeof ( DataGridAssist ) , new FrameworkPropertyMetadata ( new Thickness ( 13 , 8 , 8 , 8 ) , FrameworkPropertyMetadataOptions . Inherits ) ) ;
98+ "CellPadding" , typeof ( Thickness ) , typeof ( DataGridAssist ) ,
99+ new FrameworkPropertyMetadata ( new Thickness ( 13 , 8 , 8 , 8 ) , FrameworkPropertyMetadataOptions . Inherits ) ) ;
85100
86101 public static void SetCellPadding ( DependencyObject element , Thickness value )
87102 {
@@ -94,7 +109,8 @@ public static Thickness GetCellPadding(DependencyObject element)
94109 }
95110
96111 public static readonly DependencyProperty ColumnHeaderPaddingProperty = DependencyProperty . RegisterAttached (
97- "ColumnHeaderPadding" , typeof ( Thickness ) , typeof ( DataGridAssist ) , new FrameworkPropertyMetadata ( new Thickness ( 8 ) , FrameworkPropertyMetadataOptions . Inherits ) ) ;
112+ "ColumnHeaderPadding" , typeof ( Thickness ) , typeof ( DataGridAssist ) ,
113+ new FrameworkPropertyMetadata ( new Thickness ( 8 ) , FrameworkPropertyMetadataOptions . Inherits ) ) ;
98114
99115 public static void SetColumnHeaderPadding ( DependencyObject element , Thickness value )
100116 {
@@ -105,5 +121,102 @@ public static Thickness GetColumnHeaderPadding(DependencyObject element)
105121 {
106122 return ( Thickness ) element . GetValue ( ColumnHeaderPaddingProperty ) ;
107123 }
124+
125+
126+ public static readonly DependencyProperty EnableEditBoxAssistProperty = DependencyProperty . RegisterAttached (
127+ "EnableEditBoxAssist" , typeof ( bool ) , typeof ( DataGridAssist ) ,
128+ new PropertyMetadata ( default ( bool ) , EnableCheckBoxAssistPropertyChangedCallback ) ) ;
129+
130+ public static void SetEnableEditBoxAssist ( DependencyObject element , bool value )
131+ {
132+ element . SetValue ( EnableEditBoxAssistProperty , value ) ;
133+ }
134+
135+ public static bool GetEnableEditBoxAssist ( DependencyObject element )
136+ {
137+ return ( bool ) element . GetValue ( EnableEditBoxAssistProperty ) ;
138+ }
139+
140+ private static void EnableCheckBoxAssistPropertyChangedCallback ( DependencyObject dependencyObject ,
141+ DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs )
142+ {
143+ var dataGrid = dependencyObject as DataGrid ;
144+ if ( dataGrid == null ) return ;
145+
146+ if ( ( bool ) dependencyPropertyChangedEventArgs . NewValue )
147+ dataGrid . PreviewMouseLeftButtonDown += DataGridOnPreviewMouseLeftButtonDown ;
148+ else
149+ dataGrid . PreviewMouseLeftButtonDown -= DataGridOnPreviewMouseLeftButtonDown ;
150+ }
151+
152+ private static void DataGridOnPreviewMouseLeftButtonDown ( object sender ,
153+ MouseButtonEventArgs mouseButtonEventArgs )
154+ {
155+ var dataGrid = ( DataGrid ) sender ;
156+
157+ var inputHitTest =
158+ dataGrid . InputHitTest ( mouseButtonEventArgs . GetPosition ( ( DataGrid ) sender ) ) as DependencyObject ;
159+
160+ while ( inputHitTest != null )
161+ {
162+ var dataGridCell = inputHitTest as DataGridCell ;
163+ if ( dataGridCell != null )
164+ {
165+ ToggleButton toggleButton ;
166+ ComboBox comboBox ;
167+ if ( IsDirectHitOnEditComponent ( dataGridCell , mouseButtonEventArgs , out toggleButton ) )
168+ {
169+ dataGrid . CurrentCell = new DataGridCellInfo ( dataGridCell ) ;
170+ dataGrid . BeginEdit ( ) ;
171+ toggleButton . SetCurrentValue ( ToggleButton . IsCheckedProperty , ! toggleButton . IsChecked ) ;
172+ dataGrid . CommitEdit ( ) ;
173+ mouseButtonEventArgs . Handled = true ;
174+ }
175+ else if ( IsDirectHitOnEditComponent ( dataGridCell , mouseButtonEventArgs , out comboBox ) )
176+ {
177+ if ( _suppressComboAutoDropDown != null ) return ;
178+
179+ dataGrid . CurrentCell = new DataGridCellInfo ( dataGridCell ) ;
180+ dataGrid . BeginEdit ( ) ;
181+ //check again, as we move to the edit template
182+ if ( IsDirectHitOnEditComponent ( dataGridCell , mouseButtonEventArgs , out comboBox ) )
183+ {
184+ _suppressComboAutoDropDown = dataGrid ;
185+ comboBox . DropDownClosed += ComboBoxOnDropDownClosed ;
186+ comboBox . IsDropDownOpen = true ;
187+ }
188+ mouseButtonEventArgs . Handled = true ;
189+ }
190+
191+ return ;
192+ }
193+
194+ inputHitTest = VisualTreeHelper . GetParent ( inputHitTest ) ;
195+ }
196+ }
197+
198+ private static void ComboBoxOnDropDownClosed ( object sender , EventArgs eventArgs )
199+ {
200+ _suppressComboAutoDropDown . CommitEdit ( ) ;
201+ _suppressComboAutoDropDown = null ;
202+ ( ( ComboBox ) sender ) . DropDownClosed -= ComboBoxOnDropDownClosed ;
203+ }
204+
205+ private static bool IsDirectHitOnEditComponent < TControl > ( ContentControl contentControl , MouseEventArgs mouseButtonEventArgs , out TControl control )
206+ where TControl : Control
207+ {
208+ control = contentControl . Content as TControl ;
209+ if ( control == null ) return false ;
210+
211+ var frameworkElement = VisualTreeHelper . GetChild ( contentControl , 0 ) as FrameworkElement ;
212+ if ( frameworkElement == null ) return false ;
213+
214+ var transformToAncestor = ( MatrixTransform ) control . TransformToAncestor ( frameworkElement ) ;
215+ var rect = new Rect (
216+ new Point ( transformToAncestor . Value . OffsetX , transformToAncestor . Value . OffsetY ) ,
217+ new Size ( control . ActualWidth , control . ActualHeight ) ) ;
218+
219+ return rect . Contains ( mouseButtonEventArgs . GetPosition ( frameworkElement ) ) ;
220+ }
108221 }
109222}
0 commit comments