Skip to content

Commit 184a946

Browse files
committed
popup editor for data grid text columns
1 parent c2a6325 commit 184a946

13 files changed

+306
-56
lines changed

MaterialDesignColors.WpfExample/Domain/ListFieldsViewModel.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.ObjectModel;
1+
using System.Collections.Generic;
2+
using System.Collections.ObjectModel;
23
using System.ComponentModel;
34
using System.Runtime.CompilerServices;
45
using System.Windows.Controls;
@@ -10,6 +11,7 @@ public class ListsWindowViewModel : INotifyPropertyChanged
1011
private readonly ObservableCollection<SelectableViewModel> _items1;
1112
private readonly ObservableCollection<SelectableViewModel> _items2;
1213
private readonly ObservableCollection<SelectableViewModel> _items3;
14+
private bool? _isAllItems3Selected;
1315

1416
public ListsWindowViewModel()
1517
{
@@ -18,6 +20,30 @@ public ListsWindowViewModel()
1820
_items3 = CreateData();
1921
}
2022

23+
public bool? IsAllItems3Selected
24+
{
25+
get { return _isAllItems3Selected; }
26+
set
27+
{
28+
if (_isAllItems3Selected == value) return;
29+
30+
_isAllItems3Selected = value;
31+
32+
if (_isAllItems3Selected.HasValue)
33+
SelectAll(_isAllItems3Selected.Value, Items3);
34+
35+
OnPropertyChanged();
36+
}
37+
}
38+
39+
private void SelectAll(bool select, IEnumerable<SelectableViewModel> models)
40+
{
41+
foreach (var model in models)
42+
{
43+
model.IsSelected = select;
44+
}
45+
}
46+
2147
private static ObservableCollection<SelectableViewModel> CreateData()
2248
{
2349
return new ObservableCollection<SelectableViewModel>

MaterialDesignColors.WpfExample/Domain/SelectableViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public double Numeric
6565
_numeric = value;
6666
OnPropertyChanged();
6767
}
68-
}
68+
}
6969

7070
public event PropertyChangedEventHandler PropertyChanged;
7171

MaterialDesignColors.WpfExample/ListsWindow.xaml

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:domain="clr-namespace:MaterialDesignColors.WpfExample.Domain"
5-
Title="Lists" Height="500" Width="800">
5+
xmlns:converters="clr-namespace:MaterialDesignThemes.Wpf.Converters;assembly=MaterialDesignThemes.Wpf"
6+
xmlns:wpf="clr-namespace:MaterialDesignThemes.Wpf;assembly=MaterialDesignThemes.Wpf"
7+
Title="Lists &amp; Grids" Height="500" Width="800">
68
<Window.Resources>
79
<ResourceDictionary>
810
<ResourceDictionary.MergedDictionaries>
11+
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.DataGrid.xaml" />
912
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ToggleButton.xaml" />
1013
</ResourceDictionary.MergedDictionaries>
1114
</ResourceDictionary>
@@ -19,6 +22,7 @@
1922
<Grid.RowDefinitions>
2023
<RowDefinition Height="Auto" />
2124
<RowDefinition Height="*" />
25+
<RowDefinition Height="Auto" />
2226
</Grid.RowDefinitions>
2327
<ListBox Grid.Column="0">
2428
<TextBlock>Plain</TextBlock>
@@ -81,8 +85,61 @@
8185
</DataTemplate>
8286
</ItemsControl.ItemTemplate>
8387
</ItemsControl>
88+
89+
<TabControl Grid.Row="1" Grid.ColumnSpan="3">
90+
<TabItem Header="Custom Columns">
91+
<DataGrid ItemsSource="{Binding Items3}" CanUserSortColumns="True" CanUserAddRows="False" AutoGenerateColumns="False">
92+
<DataGrid.Columns>
93+
<DataGridCheckBoxColumn Binding="{Binding IsSelected}"
94+
ElementStyle="{StaticResource MaterialDesignDataGridCheckBoxColumnStyle}"
95+
EditingElementStyle="{StaticResource MaterialDesignDataGridCheckBoxColumnEditingStyle}">
96+
<DataGridCheckBoxColumn.Header>
97+
<!--padding to allow hit test to pass thru for sorting -->
98+
<Border Background="Transparent" Padding="6 0 6 0" HorizontalAlignment="Center">
99+
<CheckBox HorizontalAlignment="Center"
100+
DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext}"
101+
IsChecked="{Binding IsAllItems3Selected}" />
102+
</Border>
103+
</DataGridCheckBoxColumn.Header>
104+
</DataGridCheckBoxColumn>
105+
<DataGridTextColumn Binding="{Binding Code}"
106+
Header="Code"
107+
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnEditingStyle}"
108+
/>
109+
<!-- if you want to use the pop up style (MaterialDesignDataGridTextColumnPopupEditingStyle), you must use MaterialDataGridTextColumn -->
110+
<wpf:MaterialDataGridTextColumn Binding="{Binding Name}"
111+
Header="Name"
112+
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"
113+
/>
114+
<!-- set a max length to get an indicator in the editor -->
115+
<wpf:MaterialDataGridTextColumn Binding="{Binding Description}"
116+
Header="Description"
117+
MaxLength="255"
118+
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"
119+
/>
120+
<wpf:MaterialDataGridTextColumn Binding="{Binding Numeric}"
121+
Header="Numeric"
122+
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}">
123+
<DataGridTextColumn.HeaderStyle>
124+
<Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource MaterialDesignDataGridColumnHeader}">
125+
<Setter Property="HorizontalAlignment" Value="Right" />
126+
</Style>
127+
</DataGridTextColumn.HeaderStyle>
128+
<DataGridTextColumn.ElementStyle>
129+
<Style TargetType="{x:Type TextBlock}">
130+
<Setter Property="HorizontalAlignment" Value="Right" />
131+
</Style>
132+
</DataGridTextColumn.ElementStyle>
133+
</wpf:MaterialDataGridTextColumn>
134+
</DataGrid.Columns>
135+
</DataGrid>
136+
</TabItem>
137+
<TabItem Header="Auto Generated Columns">
138+
<DataGrid ItemsSource="{Binding Items3}" CanUserSortColumns="True" CanUserAddRows="False" />
139+
</TabItem>
140+
</TabControl>
141+
142+
<TextBlock Grid.Row="2" Grid.ColumnSpan="3">Looking for Material Designed Themed TabControl? Try Dragablz.</TextBlock>
84143

85-
<DataGrid ItemsSource="{Binding Items3}" CanUserSortColumns="True" CanUserAddRows="False"
86-
Grid.Row="1" Grid.ColumnSpan="3"/>
87144
</Grid>
88145
</Window>

MaterialDesignThemes.Wpf/Converters/NotConverter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Globalization;
3+
using System.Windows;
34
using System.Windows.Data;
45

56
namespace MaterialDesignThemes.Wpf.Converters
@@ -15,5 +16,5 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu
1516
{
1617
return !(value as bool?) ?? !bool.Parse(value.ToString());
1718
}
18-
}
19+
}
1920
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Windows;
4+
using System.Windows.Data;
5+
6+
namespace MaterialDesignThemes.Wpf.Converters
7+
{
8+
public class NotZeroToVisibilityConverter : IValueConverter
9+
{
10+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
11+
{
12+
double val;
13+
double.TryParse((value ?? "").ToString(), out val);
14+
15+
return Math.Abs(val) > 0.0 ? Visibility.Visible : Visibility.Collapsed;
16+
}
17+
18+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
19+
{
20+
return Binding.DoNothing;
21+
}
22+
}
23+
}
Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Windows;
23
using System.Windows.Controls;
34
using System.Windows.Controls.Primitives;
@@ -7,69 +8,76 @@ namespace MaterialDesignThemes.Wpf
78
{
89
public static class DataGridAssist
910
{
10-
public static readonly DependencyProperty AutoGeneratedCheckBoxBasedOnStyleProperty = DependencyProperty.RegisterAttached(
11-
"AutoGeneratedCheckBoxBasedOnStyle", typeof (Style), typeof (DataGridAssist), new PropertyMetadata(default(Style), AutoGeneratedCheckBoxBasedOnStylePropertyChangedCallback));
11+
public static readonly DependencyProperty AutoGeneratedCheckBoxStyleProperty = DependencyProperty.RegisterAttached(
12+
"AutoGeneratedCheckBoxStyle", typeof (Style), typeof (DataGridAssist), new PropertyMetadata(default(Style), AutoGeneratedCheckBoxStylePropertyChangedCallback));
1213

13-
private static void AutoGeneratedCheckBoxBasedOnStylePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
14+
private static void AutoGeneratedCheckBoxStylePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
1415
{
15-
//TODO un-sub, consolidate
16-
1716
((DataGrid) dependencyObject).AutoGeneratingColumn += (sender, args) =>
1817
{
1918
var dataGridCheckBoxColumn = args.Column as DataGridCheckBoxColumn;
2019
if (dataGridCheckBoxColumn == null) return;
2120

22-
var style = new Style(typeof(CheckBox), GetAutoGeneratedCheckBoxBasedOnStyle(dependencyObject));
23-
style.Setters.Add(new Setter(FrameworkElement.HorizontalAlignmentProperty, HorizontalAlignment.Center));
24-
style.Setters.Add(new Setter(UIElement.IsHitTestVisibleProperty, false));
25-
style.Setters.Add(new Setter(UIElement.FocusableProperty, false));
26-
dataGridCheckBoxColumn.ElementStyle = style;
27-
};
21+
dataGridCheckBoxColumn.ElementStyle = GetAutoGeneratedCheckBoxStyle(dependencyObject);
22+
};
2823
}
2924

30-
public static void SetAutoGeneratedCheckBoxBasedOnStyle(DependencyObject element, Style value)
25+
public static void SetAutoGeneratedCheckBoxStyle(DependencyObject element, Style value)
3126
{
32-
element.SetValue(AutoGeneratedCheckBoxBasedOnStyleProperty, value);
27+
element.SetValue(AutoGeneratedCheckBoxStyleProperty, value);
3328
}
3429

35-
public static Style GetAutoGeneratedCheckBoxBasedOnStyle(DependencyObject element)
30+
public static Style GetAutoGeneratedCheckBoxStyle(DependencyObject element)
3631
{
37-
return (Style) element.GetValue(AutoGeneratedCheckBoxBasedOnStyleProperty);
32+
return (Style) element.GetValue(AutoGeneratedCheckBoxStyleProperty);
3833
}
3934

40-
public static readonly DependencyProperty AutoGeneratedEditingCheckBoxBasedOnStyleProperty = DependencyProperty.RegisterAttached(
41-
"AutoGeneratedEditingCheckBoxBasedOnStyle", typeof (Style), typeof (DataGridAssist), new PropertyMetadata(default(Style), AutoGeneratedEditingCheckBoxBasedOnStylePropertyChangedCallback));
35+
public static readonly DependencyProperty AutoGeneratedEditingCheckBoxStyleProperty = DependencyProperty.RegisterAttached(
36+
"AutoGeneratedEditingCheckBoxStyle", typeof (Style), typeof (DataGridAssist), new PropertyMetadata(default(Style), AutoGeneratedEditingCheckBoxStylePropertyChangedCallback));
4237

43-
private static void AutoGeneratedEditingCheckBoxBasedOnStylePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
38+
private static void AutoGeneratedEditingCheckBoxStylePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
4439
{
45-
//TODO un-sub, consolidate
46-
4740
((DataGrid)dependencyObject).AutoGeneratingColumn += (sender, args) =>
4841
{
4942
var dataGridCheckBoxColumn = args.Column as DataGridCheckBoxColumn;
5043
if (dataGridCheckBoxColumn == null) return;
5144

52-
var style = new Style(typeof(CheckBox), GetAutoGeneratedCheckBoxBasedOnStyle(dependencyObject));
53-
style.Setters.Add(new Setter(FrameworkElement.HorizontalAlignmentProperty, HorizontalAlignment.Center));
54-
var binding = new Binding(((Binding) dataGridCheckBoxColumn.Binding).Path.Path)
55-
{
56-
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
57-
Mode = BindingMode.TwoWay
58-
};
59-
style.Setters.Add(new Setter(ToggleButton.IsCheckedProperty, binding));
60-
dataGridCheckBoxColumn.EditingElementStyle = style;
45+
dataGridCheckBoxColumn.EditingElementStyle = GetAutoGeneratedEditingCheckBoxStyle(dependencyObject);
6146
};
6247
}
6348

64-
public static void SetAutoGeneratedEditingCheckBoxBasedOnStyle(DependencyObject element, Style value)
49+
public static void SetAutoGeneratedEditingCheckBoxStyle(DependencyObject element, Style value)
50+
{
51+
element.SetValue(AutoGeneratedEditingCheckBoxStyleProperty, value);
52+
}
53+
54+
public static Style GetAutoGeneratedEditingCheckBoxStyle(DependencyObject element)
55+
{
56+
return (Style) element.GetValue(AutoGeneratedEditingCheckBoxStyleProperty);
57+
}
58+
59+
public static readonly DependencyProperty AutoGeneratedEditingTextStyleProperty = DependencyProperty.RegisterAttached(
60+
"AutoGeneratedEditingTextStyle", typeof (Style), typeof (DataGridAssist), new PropertyMetadata(default(Style), AutoGeneratedEditingTextStylePropertyChangedCallback));
61+
62+
private static void AutoGeneratedEditingTextStylePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
6563
{
66-
element.SetValue(AutoGeneratedEditingCheckBoxBasedOnStyleProperty, value);
64+
((DataGrid)dependencyObject).AutoGeneratingColumn += (sender, args) =>
65+
{
66+
var dataGridTextColumn = args.Column as DataGridTextColumn;
67+
if (dataGridTextColumn == null) return;
68+
69+
dataGridTextColumn.EditingElementStyle = GetAutoGeneratedEditingTextStyle(dependencyObject);
70+
};
6771
}
6872

69-
public static Style GetAutoGeneratedEditingCheckBoxBasedOnStyle(DependencyObject element)
73+
public static void SetAutoGeneratedEditingTextStyle(DependencyObject element, Style value)
7074
{
71-
return (Style) element.GetValue(AutoGeneratedEditingCheckBoxBasedOnStyleProperty);
75+
element.SetValue(AutoGeneratedEditingTextStyleProperty, value);
7276
}
7377

78+
public static Style GetAutoGeneratedEditingTextStyle(DependencyObject element)
79+
{
80+
return (Style) element.GetValue(AutoGeneratedEditingTextStyleProperty);
81+
}
7482
}
7583
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Windows;
2+
using System.Windows.Controls;
3+
4+
namespace MaterialDesignThemes.Wpf
5+
{
6+
public class MaterialDataGridTextColumn : DataGridTextColumn
7+
{
8+
protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
9+
{
10+
var textBox = editingElement as TextBox;
11+
if (textBox != null)
12+
textBox.MaxLength = MaxLength;
13+
14+
editingElement.Focus();
15+
16+
return null;
17+
}
18+
19+
/// <summary>
20+
/// Set the maximum length for the text field.
21+
/// </summary>
22+
/// <remarks>Not a dprop, as is only applied once.</remarks>
23+
public int MaxLength { get; set; }
24+
}
25+
}

MaterialDesignThemes.Wpf/MaterialDesignThemes.Wpf.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,13 @@
159159
<Compile Include="Converters\ClockItemIsCheckedConverter.cs" />
160160
<Compile Include="Converters\ClockLineConverter.cs" />
161161
<Compile Include="Converters\NotConverter.cs" />
162+
<Compile Include="Converters\NotZeroToVisibilityConverter.cs" />
162163
<Compile Include="Converters\SizeToRectConverter.cs" />
163164
<Compile Include="CustomPopupPlacementCallbackHelper.cs" />
164165
<Compile Include="DataGridAssist.cs" />
165166
<Compile Include="DateTimeEx.cs" />
166167
<Compile Include="ListSortDirectionIndicator.cs" />
168+
<Compile Include="MaterialDataGridTextColumn.cs" />
167169
<Compile Include="MaterialDateDisplay.cs" />
168170
<Compile Include="PasswordField.cs" />
169171
<Compile Include="ProgressLoop.cs" />

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.CheckBox.xaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@
8585
<Path x:Name="Graphic"
8686
Data="M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M19,5V19H5V5H19Z"
8787
Fill="{DynamicResource MaterialDesignCheckBoxOff}" />
88-
<Ellipse x:Name="InteractionEllipse" Fill="{TemplateBinding Foreground}" Width="0" Height="0" Canvas.Top="12" Canvas.Left="12" Opacity="0" RenderTransformOrigin="0.5,0.5" >
88+
<Ellipse x:Name="InteractionEllipse" Fill="{TemplateBinding Foreground}" Width="0" Height="0" Canvas.Top="12" Canvas.Left="12" Opacity="0" RenderTransformOrigin="0.5,0.5"
89+
IsHitTestVisible="False">
8990
<Ellipse.RenderTransform>
9091
<TransformGroup>
9192
<ScaleTransform/>

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.Dark.xaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
<!-- plan is to add all of the light/dark specific brushes, quite granular at first. can then consolodate any repition later on if necessary -->
66

77
<SolidColorBrush x:Key="MaterialDesignBackground" Color="#FF000000"/>
8-
<SolidColorBrush x:Key="MaterialDesignPaper" Color="#FF37474f"/>
8+
<SolidColorBrush x:Key="MaterialDesignPaper" Color="#FF37474f"/>
99
<SolidColorBrush x:Key="MaterialDesignBody" Color="#DDFFFFFF"/>
10-
10+
<SolidColorBrush x:Key="MaterialDesignColumnHeader" Color="#BCFFFFFF"/><!-- 74% -->
11+
1112
<SolidColorBrush x:Key="MaterialDesignCheckBoxOff" Color="#89FFFFFF" />
1213
<SolidColorBrush x:Key="MaterialDesignCheckBoxDisabled" Color="#4CFFFFFF" />
1314

0 commit comments

Comments
 (0)