Skip to content

Commit 50fb506

Browse files
greuelpiratKeboo
andauthored
Support search for aliases of pack icons (#1741)
* Support search for aliases of pack icons * A little cleanup so that the displayed value is always the primary enum value This keeps things a bit more consistent with the actual enum values. Co-authored-by: Kevin Bost <[email protected]>
1 parent 62ee6a0 commit 50fb506

File tree

9 files changed

+118
-48
lines changed

9 files changed

+118
-48
lines changed

MainDemo.Wpf/ButtonsViewModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.ComponentModel;
44
using System.Windows.Input;
55
using System.Windows.Threading;
6+
using MaterialDesignDemo.Domain;
67

78
namespace MaterialDesignColors.WpfExample
89
{
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using System.Collections;
3+
using System.Globalization;
4+
using System.Linq;
5+
using System.Windows.Data;
6+
7+
namespace MaterialDesignDemo.Converters
8+
{
9+
public class StringJoinConverter : IValueConverter
10+
{
11+
public string Separator { get; set; }
12+
13+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
14+
{
15+
IEnumerable values = value as IEnumerable ?? Array.Empty<object>();
16+
return string.Join(Separator ?? "", values.OfType<object>());
17+
}
18+
19+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
20+
{
21+
throw new NotImplementedException();
22+
}
23+
}
24+
}

MainDemo.Wpf/Domain/DemoItem.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.ComponentModel;
44
using System.Windows;
55
using System.Windows.Controls;
6+
using MaterialDesignDemo.Domain;
67

78
namespace MaterialDesignColors.WpfExample.Domain
89
{

MainDemo.Wpf/Domain/NotifyPropertyChangedExtension.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
using System.ComponentModel;
44
using System.Runtime.CompilerServices;
55

6-
namespace MaterialDesignColors.WpfExample.Domain
6+
namespace MaterialDesignDemo.Domain
77
{
88
public static class NotifyPropertyChangedExtension
99
{
10-
public static void MutateVerbose<TField>(this INotifyPropertyChanged instance, ref TField field, TField newValue, Action<PropertyChangedEventArgs> raise, [CallerMemberName] string propertyName = null)
10+
public static bool MutateVerbose<TField>(this INotifyPropertyChanged instance, ref TField field, TField newValue, Action<PropertyChangedEventArgs> raise, [CallerMemberName] string propertyName = null)
1111
{
12-
if (EqualityComparer<TField>.Default.Equals(field, newValue)) return;
12+
if (EqualityComparer<TField>.Default.Equals(field, newValue)) return false;
1313
field = newValue;
1414
raise?.Invoke(new PropertyChangedEventArgs(propertyName));
15+
return true;
1516
}
1617
}
1718
}

MainDemo.Wpf/Domain/TextFieldsViewModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.ComponentModel;
44
using System.Linq;
5+
using MaterialDesignDemo.Domain;
56

67
namespace MaterialDesignColors.WpfExample.Domain
78
{

MainDemo.Wpf/Domain/TreesViewModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Windows;
77
using System.Windows.Controls;
8+
using MaterialDesignDemo.Domain;
89

910
namespace MaterialDesignColors.WpfExample.Domain
1011
{

MainDemo.Wpf/IconPack.xaml

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
<UserControl x:Class="MaterialDesignDemo.IconPack"
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4-
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:materialDesignDemo="clr-namespace:MaterialDesignDemo"
77
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
88
xmlns:virtualCollection="clr-namespace:VirtualCollection.VirtualCollection"
9-
mc:Ignorable="d"
10-
d:DesignHeight="300" d:DesignWidth="300">
9+
xmlns:converters="clr-namespace:MaterialDesignDemo.Converters"
10+
xmlns:system="clr-namespace:System;assembly=mscorlib"
11+
mc:Ignorable="d"
12+
d:DesignHeight="300" d:DesignWidth="300" d:DataContext="{d:DesignInstance materialDesignDemo:IconPackViewModel}">
1113
<UserControl.Resources>
1214
<ResourceDictionary>
1315
<ResourceDictionary.MergedDictionaries>
1416
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.TextBlock.xaml" />
17+
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml" />
1518
</ResourceDictionary.MergedDictionaries>
19+
20+
<materialDesign:NullableToVisibilityConverter x:Key="NullableToVisibilityConverter" />
21+
22+
<converters:StringJoinConverter x:Key="StringJoinConverter" Separator="{x:Static system:Environment.NewLine}"/>
1623
</ResourceDictionary>
17-
</UserControl.Resources>
24+
</UserControl.Resources>
1825
<Grid>
1926
<Grid.RowDefinitions>
2027
<RowDefinition Height="Auto" />
@@ -28,24 +35,21 @@
2835
Material Design In XAML Toolkit includes the Material Design Icons collection.
2936
</TextBlock>
3037
<TextBlock Margin="0 12 0 0">
31-
For more information on Material Design Icons see the official website:
38+
For more information on Material Design Icons see the official website:
3239
<Hyperlink Command="{Binding OpenDotComCommand}">materialdesignicons.com</Hyperlink>
3340
</TextBlock>
3441
</StackPanel>
35-
<ListBox ItemsSource="{Binding Kinds}" Grid.Row="1" Margin="0 8 0 0"
36-
x:Name="KindsListBox">
42+
<ListBox ItemsSource="{Binding Kinds}" Grid.Row="1" Margin="0 8 0 0" SelectedItem="{Binding Group}">
3743
<ListBox.ItemsPanel>
3844
<ItemsPanelTemplate>
3945
<virtualCollection:VirtualizingWrapPanel ItemHeight="80" ItemWidth="80" />
4046
</ItemsPanelTemplate>
4147
</ListBox.ItemsPanel>
4248
<ListBox.ItemTemplate>
43-
<DataTemplate DataType="materialDesign:PackIconKind">
44-
<DockPanel ToolTip="{Binding }" Width="64" Height="64" Background="Transparent">
45-
<TextBlock Text="{Binding }" DockPanel.Dock="Bottom" TextTrimming="CharacterEllipsis" HorizontalAlignment="Center" />
46-
<materialDesign:PackIcon Kind="{Binding }" VerticalAlignment="Center" HorizontalAlignment="Center"
47-
Width="32" Height="32"
48-
/>
49+
<DataTemplate DataType="materialDesignDemo:PackIconKindGroup">
50+
<DockPanel ToolTip="{Binding Aliases, Converter={StaticResource StringJoinConverter}}" Width="64" Height="64" Background="Transparent">
51+
<TextBlock Text="{Binding Kind}" DockPanel.Dock="Bottom" TextTrimming="CharacterEllipsis" HorizontalAlignment="Center" />
52+
<materialDesign:PackIcon Kind="{Binding Kind}" VerticalAlignment="Center" HorizontalAlignment="Center" Width="32" Height="32" />
4953
</DockPanel>
5054
</DataTemplate>
5155
</ListBox.ItemTemplate>
@@ -58,7 +62,7 @@
5862
<ColumnDefinition Width="Auto" />
5963
<ColumnDefinition Width="*" />
6064
</Grid.ColumnDefinitions>
61-
<Button Style="{DynamicResource MaterialDesignToolButton}"
65+
<Button Style="{DynamicResource MaterialDesignToolButton}"
6266
Command="{Binding SearchCommand}" x:Name="SearchButton"
6367
CommandParameter="{Binding ElementName=SearchBox, Path=Text}"
6468
Height="24" Width="24">
@@ -78,16 +82,17 @@
7882
FontFamily="Courier New"
7983
FontWeight="Bold"
8084
GotFocus="TextBox_OnGotFocus"
81-
Text="{Binding ElementName=KindsListBox, Path=SelectedValue, StringFormat='&lt;materialDesign:PackIcon Kind=&quot;{0}&quot; \/>'}" />
85+
Text="{Binding Kind, StringFormat='&lt;materialDesign:PackIcon Kind=&quot;{0}&quot; \/>'}" />
8286
</materialDesign:ColorZone>
83-
<materialDesign:PackIcon Kind="{Binding ElementName=KindsListBox, Path=SelectedValue}" VerticalAlignment="Center" />
84-
<Button Margin="8 0" Command="{Binding CopyToClipboardCommand, Mode=OneTime}" CommandParameter="{Binding ElementName=KindsListBox, Path=SelectedValue}">
87+
<materialDesign:PackIcon Kind="{Binding Kind}" VerticalAlignment="Center"
88+
Visibility="{Binding Kind, Converter={StaticResource NullableToVisibilityConverter}}" />
89+
<Button Margin="8 0" Command="{Binding CopyToClipboardCommand, Mode=OneTime}" CommandParameter="{Binding Kind}">
8590
<StackPanel Orientation="Horizontal">
86-
<materialDesign:PackIcon Kind="ContentCopy"/>
91+
<materialDesign:PackIcon Kind="ContentCopy" />
8792
<TextBlock Text="Copy To Clipboard" Margin="8 0 0 0" />
8893
</StackPanel>
8994
</Button>
9095
</StackPanel>
9196
</materialDesign:ColorZone>
9297
</Grid>
93-
</UserControl>
98+
</UserControl>

MainDemo.Wpf/IconPackViewModel.cs

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
using System;
22
using System.Collections.Generic;
33
using System.ComponentModel;
4-
using System.Diagnostics;
54
using System.Linq;
6-
using System.Runtime.CompilerServices;
5+
using System.Threading.Tasks;
76
using System.Windows;
87
using System.Windows.Input;
98
using MaterialDesignColors.WpfExample.Domain;
@@ -14,7 +13,7 @@ namespace MaterialDesignDemo
1413
{
1514
public class IconPackViewModel : INotifyPropertyChanged
1615
{
17-
private readonly Lazy<IEnumerable<PackIconKind>> _packIconKinds;
16+
private readonly Lazy<IEnumerable<PackIconKindGroup>> _packIconKinds;
1817
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
1918

2019
public IconPackViewModel(ISnackbarMessageQueue snackbarMessageQueue)
@@ -24,58 +23,72 @@ public IconPackViewModel(ISnackbarMessageQueue snackbarMessageQueue)
2423
OpenDotComCommand = new AnotherCommandImplementation(OpenDotCom);
2524
SearchCommand = new AnotherCommandImplementation(Search);
2625
CopyToClipboardCommand = new AnotherCommandImplementation(CopyToClipboard);
27-
_packIconKinds = new Lazy<IEnumerable<PackIconKind>>(() =>
28-
Enum.GetValues(typeof(PackIconKind))
29-
.OfType<PackIconKind>()
30-
.Distinct()
31-
.OrderBy(k => k.ToString(), StringComparer.InvariantCultureIgnoreCase).ToList()
32-
);
26+
27+
_packIconKinds = new Lazy<IEnumerable<PackIconKindGroup>>(() =>
28+
Enum.GetNames(typeof(PackIconKind))
29+
.GroupBy(k => (PackIconKind) Enum.Parse(typeof(PackIconKind), k))
30+
.Select(g => new PackIconKindGroup(g))
31+
.OrderBy(x => x.Kind)
32+
.ToList());
3333
}
3434

3535
public ICommand OpenDotComCommand { get; }
3636
public ICommand SearchCommand { get; }
3737
public ICommand CopyToClipboardCommand { get; }
3838

39-
private IEnumerable<PackIconKind> _kinds;
40-
public IEnumerable<PackIconKind> Kinds
39+
private IEnumerable<PackIconKindGroup> _kinds;
40+
private PackIconKindGroup _group;
41+
private string _kind;
42+
43+
public IEnumerable<PackIconKindGroup> Kinds
44+
{
45+
get => _kinds ??= _packIconKinds.Value;
46+
set => this.MutateVerbose(ref _kinds, value, e => PropertyChanged?.Invoke(this, e));
47+
}
48+
49+
public PackIconKindGroup Group
4150
{
42-
get { return _kinds ?? (_kinds = _packIconKinds.Value); }
51+
get => _group;
4352
set
4453
{
45-
_kinds = value;
46-
OnPropertyChanged();
54+
if (this.MutateVerbose(ref _group, value, e => PropertyChanged?.Invoke(this, e)))
55+
{
56+
Kind = value?.Kind;
57+
}
58+
4759
}
4860
}
4961

62+
public string Kind
63+
{
64+
get => _kind;
65+
set => this.MutateVerbose(ref _kind, value, e => PropertyChanged?.Invoke(this, e));
66+
}
67+
5068
private void OpenDotCom(object obj)
5169
{
5270
Link.OpenInBrowser("https://materialdesignicons.com/");
5371
}
5472

55-
private void Search(object obj)
73+
private async void Search(object obj)
5674
{
5775
var text = obj as string;
5876
if (string.IsNullOrWhiteSpace(text))
5977
Kinds = _packIconKinds.Value;
6078
else
61-
Kinds =
62-
_packIconKinds.Value.Where(
63-
x => x.ToString().IndexOf(text, StringComparison.CurrentCultureIgnoreCase) >= 0);
79+
{
80+
Kinds = await Task.Run(() => _packIconKinds.Value
81+
.Where(x => x.Aliases.Any(a => a.IndexOf(text, StringComparison.CurrentCultureIgnoreCase) >= 0))
82+
.ToList());}
6483
}
6584

6685
private void CopyToClipboard(object obj)
6786
{
68-
var kind = (PackIconKind?)obj;
69-
string toBeCopied = $"<materialDesign:PackIcon Kind=\"{kind}\" />";
87+
var toBeCopied = $"<materialDesign:PackIcon Kind=\"{obj}\" />";
7088
Clipboard.SetDataObject(toBeCopied);
7189
_snackbarMessageQueue.Enqueue(toBeCopied + " copied to clipboard");
7290
}
7391

7492
public event PropertyChangedEventHandler PropertyChanged;
75-
76-
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
77-
{
78-
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
79-
}
8093
}
81-
}
94+
}

MainDemo.Wpf/PackIconKindGroup.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace MaterialDesignDemo
6+
{
7+
public class PackIconKindGroup
8+
{
9+
public PackIconKindGroup(IEnumerable<string> kinds)
10+
{
11+
if (kinds is null) throw new ArgumentNullException(nameof(kinds));
12+
var allValues = kinds.ToList();
13+
if (!allValues.Any()) throw new ArgumentException($"{nameof(kinds)} must contain at least one value");
14+
Kind = allValues.First();
15+
Aliases = allValues
16+
.OrderBy(x => x, StringComparer.InvariantCultureIgnoreCase)
17+
.ToArray();
18+
}
19+
20+
public string Kind { get; }
21+
public string[] Aliases { get; }
22+
}
23+
}

0 commit comments

Comments
 (0)