Skip to content

Commit 12df710

Browse files
Refactor DataGridAssist.ApplyMaterialDesignColumnStyles to use AP
The assist class now uses the attached properties associated with the corresponding DataGrid. Introduced a ColumnUpdater type and a private DP in order to have a reference to the DataGrid in the Columns_CollectionChanged() callback and to do proper housekeeping/cleanup to avoid memory leaks.
1 parent 274624b commit 12df710

File tree

2 files changed

+86
-55
lines changed

2 files changed

+86
-55
lines changed

MaterialDesignThemes.Wpf/DataGridAssist.cs

Lines changed: 80 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Specialized;
12
using System.Windows.Media;
23

34
namespace MaterialDesignThemes.Wpf;
@@ -187,79 +188,103 @@ public static void SetApplyMaterialDesignColumnStyles(DataGrid element, bool val
187188
public static bool GetApplyMaterialDesignColumnStyles(DataGrid element)
188189
=> (bool) element.GetValue(ApplyMaterialDesignColumnStylesProperty);
189190

191+
192+
private static readonly DependencyProperty ColumnUpdaterProperty
193+
= DependencyProperty.RegisterAttached("ColumnUpdater", typeof(ColumnUpdater), typeof(DataGridAssist),
194+
new PropertyMetadata(default(ColumnUpdater)));
195+
private static void SetColumnUpdater(DependencyObject element, ColumnUpdater? value) => element.SetValue(ColumnUpdaterProperty, value);
196+
private static ColumnUpdater? GetColumnUpdater(DependencyObject element) => (ColumnUpdater?) element.GetValue(ColumnUpdaterProperty);
197+
190198
private static void ApplyMaterialDesignColumnStylesPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
191199
{
192200
var dataGrid = (DataGrid)d;
193-
194-
dataGrid.Columns.CollectionChanged -= Columns_CollectionChanged;
201+
ColumnUpdater? columnUpdater = GetColumnUpdater(dataGrid);
202+
if (columnUpdater is not { })
203+
{
204+
columnUpdater = new ColumnUpdater(dataGrid);
205+
}
206+
dataGrid.Columns.CollectionChanged -= columnUpdater.Columns_CollectionChanged;
195207
if (Equals(true, e.NewValue))
196208
{
197-
dataGrid.Columns.CollectionChanged += Columns_CollectionChanged; // Auto-generated columns are added later in the chain, thus we subscribe to changes.
209+
SetColumnUpdater(dataGrid, columnUpdater);
210+
dataGrid.Columns.CollectionChanged += columnUpdater.Columns_CollectionChanged; // Auto-generated columns are added later in the chain, thus we subscribe to changes.
198211
foreach (var column in dataGrid.Columns)
199212
{
200-
ApplyMaterialDesignColumnStyleForColumn(column);
213+
ColumnUpdater.ApplyMaterialDesignColumnStyleForColumn(dataGrid, column);
201214
}
202215
}
203-
}
204-
205-
private static void Columns_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
206-
{
207-
foreach (DataGridColumn column in e.NewItems?.OfType<DataGridColumn>() ?? Enumerable.Empty<DataGridColumn>())
216+
else
208217
{
209-
ApplyMaterialDesignColumnStyleForColumn(column);
218+
dataGrid.ClearValue(ColumnUpdaterProperty);
210219
}
211220
}
212221

213-
private static void ApplyMaterialDesignColumnStyleForColumn(DataGridColumn column)
222+
private class ColumnUpdater
214223
{
215-
Style defaultElementStyle = (Style)DataGridBoundColumn.ElementStyleProperty.GetMetadata(column.GetType()).DefaultValue;
216-
Style defaultEditingElementStyle = (Style)DataGridBoundColumn.EditingElementStyleProperty.GetMetadata(column.GetType()).DefaultValue;
224+
private readonly DataGrid _dataGrid;
217225

218-
bool applyElementStyle;
219-
bool applyEditingElementStyle;
220-
switch (column)
226+
public ColumnUpdater(DataGrid dataGrid) => _dataGrid = dataGrid;
227+
228+
public void Columns_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
229+
{
230+
foreach (DataGridColumn column in e.NewItems?.OfType<DataGridColumn>() ?? Enumerable.Empty<DataGridColumn>())
231+
{
232+
ApplyMaterialDesignColumnStyleForColumn(_dataGrid, column);
233+
}
234+
}
235+
236+
public static void ApplyMaterialDesignColumnStyleForColumn(DataGrid dataGrid, DataGridColumn column)
221237
{
222-
case DataGridCheckBoxColumn checkBoxColumn:
223-
applyElementStyle = Equals(checkBoxColumn.ElementStyle, defaultElementStyle);
224-
applyEditingElementStyle = Equals(checkBoxColumn.EditingElementStyle, defaultEditingElementStyle);
225-
if (applyElementStyle)
226-
{
227-
checkBoxColumn.ElementStyle = (Style)Application.Current.TryFindResource("MaterialDesignDataGridCheckBoxColumnStyle");
228-
}
229-
230-
if (applyEditingElementStyle)
231-
{
232-
checkBoxColumn.EditingElementStyle = (Style)Application.Current.TryFindResource("MaterialDesignDataGridCheckBoxColumnEditingStyle");
233-
}
234-
break;
235-
case System.Windows.Controls.DataGridTextColumn textColumn:
236-
applyElementStyle = Equals(textColumn.ElementStyle, defaultElementStyle);
237-
applyEditingElementStyle = Equals(textColumn.EditingElementStyle, defaultEditingElementStyle);
238-
if (applyElementStyle)
239-
{
240-
textColumn.ElementStyle = (Style)Application.Current.TryFindResource("MaterialDesignDataGridTextColumnStyle");
241-
}
242-
243-
if (applyEditingElementStyle)
244-
{
245-
textColumn.EditingElementStyle = (Style)Application.Current.TryFindResource("MaterialDesignDataGridTextColumnEditingStyle");
246-
}
247-
break;
248-
case System.Windows.Controls.DataGridComboBoxColumn comboBoxColumn:
249-
applyElementStyle = Equals(comboBoxColumn.ElementStyle, defaultElementStyle);
250-
applyEditingElementStyle = Equals(comboBoxColumn.EditingElementStyle, defaultEditingElementStyle);
251-
if (applyElementStyle)
252-
{
253-
comboBoxColumn.ElementStyle = (Style)Application.Current.TryFindResource(new ComponentResourceKey(typeof(ComboBox), "MaterialDataGridComboBoxColumnStyle"));
254-
}
255-
256-
if (applyEditingElementStyle)
257-
{
258-
comboBoxColumn.EditingElementStyle = (Style)Application.Current.TryFindResource(new ComponentResourceKey(typeof(ComboBox), "MaterialDataGridComboBoxColumnEditingStyle"));
259-
}
260-
break;
238+
Style defaultElementStyle = (Style)DataGridBoundColumn.ElementStyleProperty.GetMetadata(column.GetType()).DefaultValue;
239+
Style defaultEditingElementStyle = (Style)DataGridBoundColumn.EditingElementStyleProperty.GetMetadata(column.GetType()).DefaultValue;
240+
241+
bool applyElementStyle;
242+
bool applyEditingElementStyle;
243+
switch (column)
244+
{
245+
case DataGridCheckBoxColumn checkBoxColumn:
246+
applyElementStyle = Equals(checkBoxColumn.ElementStyle, defaultElementStyle);
247+
applyEditingElementStyle = Equals(checkBoxColumn.EditingElementStyle, defaultEditingElementStyle);
248+
if (applyElementStyle && GetAutoGeneratedCheckBoxStyle(dataGrid) is { } checkBoxElementStyle)
249+
{
250+
checkBoxColumn.ElementStyle = checkBoxElementStyle;
251+
}
252+
253+
if (applyEditingElementStyle && GetAutoGeneratedEditingCheckBoxStyle(dataGrid) is { } checkBoxEditingElementStyle)
254+
{
255+
checkBoxColumn.EditingElementStyle = checkBoxEditingElementStyle;
256+
}
257+
break;
258+
case System.Windows.Controls.DataGridTextColumn textColumn:
259+
applyElementStyle = Equals(textColumn.ElementStyle, defaultElementStyle);
260+
applyEditingElementStyle = Equals(textColumn.EditingElementStyle, defaultEditingElementStyle);
261+
if (applyElementStyle && GetAutoGeneratedTextStyle(dataGrid) is { } textElementStyle)
262+
{
263+
textColumn.ElementStyle = textElementStyle;
264+
}
265+
266+
if (applyEditingElementStyle && GetAutoGeneratedEditingTextStyle(dataGrid) is { } textEditingElementStyle)
267+
{
268+
textColumn.EditingElementStyle = textEditingElementStyle;
269+
}
270+
break;
271+
case System.Windows.Controls.DataGridComboBoxColumn comboBoxColumn:
272+
applyElementStyle = Equals(comboBoxColumn.ElementStyle, defaultElementStyle);
273+
applyEditingElementStyle = Equals(comboBoxColumn.EditingElementStyle, defaultEditingElementStyle);
274+
if (applyElementStyle && GetAutoGeneratedComboBoxStyle(dataGrid) is { } comboBoxElementStyle)
275+
{
276+
comboBoxColumn.ElementStyle = comboBoxElementStyle;
277+
}
278+
279+
if (applyEditingElementStyle && GetAutoGeneratedEditingComboBoxStyle(dataGrid) is { } comboBoxEditingElementStyle)
280+
{
281+
comboBoxColumn.EditingElementStyle = comboBoxEditingElementStyle;
282+
}
283+
break;
284+
}
261285
}
262286
}
287+
263288
#endregion
264289

265290
#region AttachedProperty : CellPaddingProperty

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.DataGrid.xaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,12 @@
549549
</Setter.Value>
550550
</Setter>
551551
<Setter Property="VerticalGridLinesBrush" Value="{Binding HorizontalGridLinesBrush, RelativeSource={RelativeSource Self}}" />
552+
<Setter Property="wpf:DataGridAssist.AutoGeneratedCheckBoxStyle" Value="{StaticResource MaterialDesignDataGridCheckBoxColumnStyle}" />
553+
<Setter Property="wpf:DataGridAssist.AutoGeneratedEditingCheckBoxStyle" Value="{StaticResource MaterialDesignDataGridCheckBoxColumnEditingStyle}" />
554+
<Setter Property="wpf:DataGridAssist.AutoGeneratedEditingTextStyle" Value="{StaticResource MaterialDesignDataGridTextColumnEditingStyle}" />
555+
<Setter Property="wpf:DataGridAssist.AutoGeneratedTextStyle" Value="{StaticResource MaterialDesignDataGridTextColumnStyle}" />
556+
<Setter Property="wpf:DataGridAssist.AutoGeneratedEditingComboBoxStyle" Value="{x:Static wpf:DataGridComboBoxColumn.DefaultEditingElementStyle}" />
557+
<Setter Property="wpf:DataGridAssist.AutoGeneratedComboBoxStyle" Value="{x:Static wpf:DataGridComboBoxColumn.DefaultElementStyle}" />
552558
<Setter Property="wpf:DataGridAssist.ApplyMaterialDesignColumnStyles" Value="true" />
553559
<Setter Property="wpf:DataGridAssist.EnableEditBoxAssist" Value="True" />
554560
<Setter Property="wpf:DataGridAssist.SelectedCellBorderBrush" Value="{DynamicResource MaterialDesignTextBoxBorder}" />

0 commit comments

Comments
 (0)