From 41db02ff49d610d10352bcadb7f9291b0e19deda Mon Sep 17 00:00:00 2001 From: Peter Kuhn Date: Mon, 1 Jul 2024 13:04:20 +0200 Subject: [PATCH 1/4] Add the posibility to show the colors of an MahApps Theme --- src/IconPacks.Browser/MainWindow.xaml | 927 ++++++++++++------ src/IconPacks.Browser/MainWindow.xaml.cs | 19 + src/IconPacks.Browser/Model/ThemeResource.cs | 162 +++ .../ViewModels/IconPackViewModel.cs | 3 + .../ViewModels/MainViewModel.cs | 13 +- .../ViewModels/ThemeResourcesViewModel.cs | 244 +++++ 6 files changed, 1049 insertions(+), 319 deletions(-) create mode 100644 src/IconPacks.Browser/Model/ThemeResource.cs create mode 100644 src/IconPacks.Browser/ViewModels/ThemeResourcesViewModel.cs diff --git a/src/IconPacks.Browser/MainWindow.xaml b/src/IconPacks.Browser/MainWindow.xaml index 5d9df84..d3ea567 100644 --- a/src/IconPacks.Browser/MainWindow.xaml +++ b/src/IconPacks.Browser/MainWindow.xaml @@ -1,35 +1,37 @@ - + - + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/IconPacks.Browser/MainWindow.xaml.cs b/src/IconPacks.Browser/MainWindow.xaml.cs index 504677b..248111f 100644 --- a/src/IconPacks.Browser/MainWindow.xaml.cs +++ b/src/IconPacks.Browser/MainWindow.xaml.cs @@ -1,3 +1,5 @@ +using System.Windows; +using System.Windows.Controls; using System.Windows.Input; using IconPacks.Browser.Properties; using IconPacks.Browser.ViewModels; @@ -35,5 +37,22 @@ private void Find_Executed(object sender, System.Windows.Input.ExecutedRoutedEve FilterTextBox.Focus(); Keyboard.Focus(FilterTextBox); } + + /// + /// Forward Cell click + /// + /// + /// + private void DataGridCell_MouseDoubleClick(object sender, MouseButtonEventArgs e) + { + if (sender is DataGridCell c && c.TryFindParent()!=null) + { + var frm = c.TryFindParent(); + if (frm.DataContext !=null && frm.DataContext is MainViewModel mvm) + { + mvm.ThemeResourcesViewModel.DataGridCell_MouseDoubleClick(sender,e); + } + } + } } } \ No newline at end of file diff --git a/src/IconPacks.Browser/Model/ThemeResource.cs b/src/IconPacks.Browser/Model/ThemeResource.cs new file mode 100644 index 0000000..07be9db --- /dev/null +++ b/src/IconPacks.Browser/Model/ThemeResource.cs @@ -0,0 +1,162 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Windows; +using System.Windows.Media; +using ControlzEx.Theming; +using IconPacks.Browser.ViewModels; +using JetBrains.Annotations; + +namespace IconPacks.Browser.Model +{ + /// + /// Clas for one single resource color in light and dark + /// + public class ThemeResource : ViewModelBase + { + private bool isHidden = false; + + public ThemeResource(Theme theme, LibraryTheme libraryTheme, ResourceDictionary resourceDictionary, DictionaryEntry dictionaryEntryDark, DictionaryEntry dictionaryEntryLight) + : this(theme, libraryTheme, resourceDictionary, dictionaryEntryDark.Key.ToString(), dictionaryEntryDark.Value, dictionaryEntryLight.Value) + { + } + + public ThemeResource(Theme theme, LibraryTheme libraryTheme, ResourceDictionary resourceDictionary, string? key, object? valueDark, object? valueLight) + { + this.Theme = theme; + this.LibraryTheme = libraryTheme; + + this.Source = (resourceDictionary.Source?.ToString() ?? "Runtime").ToLower(); + this.Source = CultureInfo.InstalledUICulture.TextInfo.ToTitleCase(this.Source) + .Replace("Pack", "pack") + .Replace("Application", "application") + .Replace("Xaml", "xaml"); + + this.Key = key; + + this.ValueLight = valueLight switch + { + Color color => new SolidColorBrush(color), + Brush brush => brush, + _ => null + }; + + this.AlphaLight = valueLight switch + { + Color color => color.A, + SolidColorBrush brush => brush.Color.A, + LinearGradientBrush brush => brush.GradientStops[0].Color.A, + _ => 255 + }; + + this.StringValueLight = valueLight?.ToString(); + + this.ValueDark = valueDark switch + { + Color color => new SolidColorBrush(color), + Brush brush => brush, + _ => null + }; + + this.AlphaDark = valueDark switch + { + Color color => color.A, + SolidColorBrush brush => brush.Color.A, + LinearGradientBrush brush => brush.GradientStops[0].Color.A, + _ => 255 + }; + + this.StringValueDark = valueDark?.ToString(); + } + + /// + /// The current selected theme. Switch in Settings of App + /// + public Theme Theme { get; } + + /// + /// The current selected theme. Switch in Settings of App + /// + public LibraryTheme LibraryTheme { get; } + + /// + /// Source of this theme + /// + public string Source { get; } + + /// + /// Key of this resource + /// + public string? Key { get; } + + /// + /// The light color of this resource + /// + public Brush? ValueLight { get; } + /// + /// The alpha value of this light color + /// + public int AlphaLight { get; } = 0; + /// + /// The light color as hex string + /// + public string? StringValueLight { get; } + /// + /// The dark color + /// + public Brush? ValueDark { get; } + /// + /// Alpha channel of dark color + /// + public int AlphaDark { get; } = 0; + /// + /// the dark color as hex string + /// + public string? StringValueDark { get; } + /// + /// when tru, don't show in grid + /// + public bool IsHidden + { + get => isHidden; set + { + if (Set(ref isHidden, value)) + { + + } + } + } + + /// + /// Filter like it's done in icons + /// + /// + /// + public bool CheckFilter(string filterText) + { + bool RetVal = true; + if (!string.IsNullOrWhiteSpace(filterText)) + { + var filterSubStrings = filterText.Split(new[] { '+', ',', ';', '&' }, StringSplitOptions.RemoveEmptyEntries); + + foreach (var filterSubString in filterSubStrings) + { + var filterOrSubStrings = filterSubString.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); + + var isInName = filterOrSubStrings.Any(x => Key.IndexOf(x.Trim(), StringComparison.CurrentCultureIgnoreCase) >= 0); + + if (!isInName) RetVal = false; + } + } + return RetVal; + } + + } +} \ No newline at end of file diff --git a/src/IconPacks.Browser/ViewModels/IconPackViewModel.cs b/src/IconPacks.Browser/ViewModels/IconPackViewModel.cs index 16b5fcc..4e18b08 100644 --- a/src/IconPacks.Browser/ViewModels/IconPackViewModel.cs +++ b/src/IconPacks.Browser/ViewModels/IconPackViewModel.cs @@ -466,6 +466,7 @@ private async void SaveAsBitmapExecute(BitmapEncoder encoder) public interface IIconViewModel { string Name { get; set; } + string FullName { get; } string IconPackName { get; } string Description { get; set; } Type IconPackType { get; set; } @@ -484,6 +485,7 @@ public class IconViewModel : IIconViewModel public IconViewModel(Type enumType, Type packType, Enum k, MetaDataAttribute metaData) { Name = k.ToString(); + FullName = enumType.FullName + "." + k.ToString(); Description = GetDescription(k); IconPackType = packType; IconType = enumType; @@ -501,6 +503,7 @@ public IconViewModel(Type enumType, Type packType, Enum k, MetaDataAttribute met public string CopyToClipboardAsGeometryText => ExportHelper.FillTemplate(ExportHelper.ClipboardData, new ExportParameters(this)); // GetPackIconControlBase().Data; public string Name { get; set; } + public string FullName { get; } public string IconPackName => IconPackType.Name.Replace("PackIcon", ""); diff --git a/src/IconPacks.Browser/ViewModels/MainViewModel.cs b/src/IconPacks.Browser/ViewModels/MainViewModel.cs index 63c968d..32d13a2 100644 --- a/src/IconPacks.Browser/ViewModels/MainViewModel.cs +++ b/src/IconPacks.Browser/ViewModels/MainViewModel.cs @@ -5,10 +5,14 @@ using System.Linq; using System.Reflection; using System.Windows; +using System.Windows.Controls.Primitives; +using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; using MahApps.Metro.Controls.Dialogs; using MahApps.Metro.IconPacks; +using IconPacks.Browser.Model; +using ControlzEx.Theming; namespace IconPacks.Browser.ViewModels { @@ -98,6 +102,8 @@ public MainViewModel(Dispatcher dispatcher) this.IconPacksVersion = FileVersionInfo.GetVersionInfo(Assembly.GetAssembly(typeof(PackIconMaterial)).Location).FileVersion; this.Settings = new SettingsViewModel(this.dialogCoordinator); + + ThemeManager.Current.ThemeChanged += this.ThemeResourcesViewModel.ThemeManager_ThemeChanged; } private static async void OpenUrlLink(string link) @@ -214,8 +220,13 @@ private static void DoCopyTextToClipboard(string text) { CanExecuteDelegate = x => (x is IIconViewModel), ExecuteDelegate = x => DoCopyTextToClipboard(((IIconViewModel)x).CopyToClipboardAsGeometryText) - }; + }; public SettingsViewModel Settings { get; } + + + public ThemeResourcesViewModel ThemeResourcesViewModel { get; } = new ThemeResourcesViewModel(); + + } } \ No newline at end of file diff --git a/src/IconPacks.Browser/ViewModels/ThemeResourcesViewModel.cs b/src/IconPacks.Browser/ViewModels/ThemeResourcesViewModel.cs new file mode 100644 index 0000000..39af36d --- /dev/null +++ b/src/IconPacks.Browser/ViewModels/ThemeResourcesViewModel.cs @@ -0,0 +1,244 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Threading; +using ControlzEx.Theming; +using IconPacks.Browser.Model; +using IconPacks.Browser.ViewModels; +using JetBrains.Annotations; + +namespace IconPacks.Browser.ViewModels +{ + /// + /// Viewmodel for Color Resources + /// + public class ThemeResourcesViewModel : ViewModelBase + { + private DispatcherTimer timer = new DispatcherTimer(); + private string header = "Colors"; + private string _filterTextColors; + private string statusColorFilter; + private int filterAlphaValue = 0; + + /// + /// this are the resources of this theme + /// + public ObservableCollection ThemeResources { get; } = new ObservableCollection(); + + public ThemeResourcesViewModel() + { + timer.Interval = TimeSpan.FromSeconds(3); + timer.Tick += Timer_Tick; + } + + /// + /// Disables the popup + /// + /// + /// + private void Timer_Tick(object sender, EventArgs e) + { + PopupIsOpen = false; + this.OnPropertyChanged(nameof(PopupIsOpen)); + timer.Stop(); + } + + /// + /// Theme changed==Updat colors + /// + /// + /// + internal void ThemeManager_ThemeChanged(object? sender, ThemeChangedEventArgs e) + { + UpdateThemeResources(); + } + + /// + /// Show the current Theme + /// + public string Header + { + get => header; set + { + header = value; + this.OnPropertyChanged(nameof(Header)); + } + } + + /// + /// Popup for doublick infomation + /// + public bool PopupIsOpen { get; set; } + public object PopupPlacementTarget { get; set; } + public string PopupText { get; set; } + + /// + /// Only colors with alpha channel greater this value will be shown + /// + public int FilterAlphaValue + { + get => filterAlphaValue; set + { + if (Set(ref filterAlphaValue, value)) + { + Filter(); + } + } + } + + /// + /// Search Textbox like it was for icons + /// + public string FilterTextColors + { + get => _filterTextColors; + set + { + if (Set(ref _filterTextColors, value)) + { + Filter(); + } + } + } + + /// + /// For Statusbar, count of colors visible + /// + public string StatusColorFilter + { + get => statusColorFilter; set + { + Set(ref statusColorFilter, value); + } + } + + /// + /// Filter the resources, IsHidden=true means not visible + /// + private void Filter() + { + var colorCount = 0; + foreach (var item in ThemeResources) + { + item.IsHidden = !item.CheckFilter(_filterTextColors) || item.AlphaLight< filterAlphaValue || item.AlphaDark< filterAlphaValue; + if (!item.IsHidden) colorCount += 1; + } + var filtered = (colorCount != ThemeResources.Count) ? " (filtered)" : ""; + StatusColorFilter = $"{Header} with {colorCount} Colors{filtered}"; + } + + /// + /// Forwarded from code behind. Sorry. MVVM to complicated for me :) + /// + /// + /// + public void DataGridCell_MouseDoubleClick(object sender, MouseButtonEventArgs e) + { + if (sender != null && sender is DataGridCell cell && cell.DataContext != null && cell.DataContext is ThemeResource tr) + { + PopupText = ""; + if (cell.Column.DisplayIndex == 0) + { + System.Windows.Clipboard.SetText(tr.Key); + PopupText = $"Resourcename \"{tr.Key}\" copied to clipboard"; + } + else if (cell.Column.DisplayIndex == 1 || cell.Column.DisplayIndex == 2) + { + System.Windows.Clipboard.SetText(tr.StringValueLight); + PopupText = $"hex-value for light theme \"{tr.StringValueLight}\" copied to clipboard"; + } + else if (cell.Column.DisplayIndex == 3 || cell.Column.DisplayIndex == 4) + { + System.Windows.Clipboard.SetText(tr.StringValueDark); + PopupText = $"hex-value for dark theme \"{tr.StringValueDark}\" copied to clipboard"; + } + + + if (!string.IsNullOrEmpty(PopupText)) + { + PopupPlacementTarget = sender; + this.OnPropertyChanged(nameof(PopupPlacementTarget)); + this.OnPropertyChanged(nameof(PopupText)); + + PopupIsOpen = true; + this.OnPropertyChanged(nameof(PopupIsOpen)); + + timer.Start(); + } + + } + } + + /// + /// When Theme Changed, update the colos + /// + public void UpdateThemeResources() + { + this.ThemeResources.Clear(); + + if (Application.Current.MainWindow != null) + { + var themeOriginal = ThemeManager.Current.DetectTheme(Application.Current.MainWindow); + string Accent = ""; + foreach (var t in ThemeManager.Current.Themes) + { + if (t.PrimaryAccentColor.Equals(themeOriginal.PrimaryAccentColor)) + { + Accent = t.ColorScheme; + break; + } + } + + Header = $"App color: {Accent}"; + + + if (themeOriginal is not null) + { + var themeDark = ThemeManager.Current.GetTheme("Dark", Accent); + var themeLight = ThemeManager.Current.GetTheme("Light", Accent); + + if (themeDark != null && themeLight != null) + { + var libraryThemeDark = themeDark.LibraryThemes.FirstOrDefault(x => x.Origin == "MahApps.Metro"); + var resourceDictionaryDark = libraryThemeDark?.Resources.MergedDictionaries.FirstOrDefault(); + + var libraryThemeLight = themeLight.LibraryThemes.FirstOrDefault(x => x.Origin == "MahApps.Metro"); + var resourceDictionaryLight = libraryThemeLight?.Resources.MergedDictionaries.FirstOrDefault(); + + if (resourceDictionaryDark != null && resourceDictionaryLight != null) + { + var colorCount = 0; + foreach (var dictionaryEntryDark in resourceDictionaryDark.OfType()) + { + var dictionaryEntryLight = dictionaryEntryDark.Value; + + if (resourceDictionaryLight.Contains(dictionaryEntryDark.Key)) dictionaryEntryLight = resourceDictionaryLight[dictionaryEntryDark.Key]; + var tr = new ThemeResource(themeDark, libraryThemeDark!, resourceDictionaryDark, dictionaryEntryDark.Key.ToString(), dictionaryEntryDark.Value, dictionaryEntryLight); + //tr.isHidden = OnlyFullAlpha && (!tr.FullAlpha || !tr.FullAlphaDark); + + if (!tr.IsHidden) colorCount += 1; + this.ThemeResources.Add(tr); + } + FilterTextColors = ""; + } + } + + } + + } + } + } +} \ No newline at end of file From b64918ca79738a0192063b73e051dcb25fc64941 Mon Sep 17 00:00:00 2001 From: Peter Kuhn Date: Mon, 1 Jul 2024 13:18:30 +0200 Subject: [PATCH 2/4] All Nuget Updates done --- src/IconPacks.Browser/IconPacks.Browser.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/IconPacks.Browser/IconPacks.Browser.csproj b/src/IconPacks.Browser/IconPacks.Browser.csproj index 9761df2..52a5f5b 100644 --- a/src/IconPacks.Browser/IconPacks.Browser.csproj +++ b/src/IconPacks.Browser/IconPacks.Browser.csproj @@ -26,13 +26,13 @@ - + - + - - + + From a8b829638904fc8745d49a9e9630c5e74b27828f Mon Sep 17 00:00:00 2001 From: Peter Kuhn Date: Mon, 1 Jul 2024 16:16:22 +0200 Subject: [PATCH 3/4] wip Export to .ico file. wip is currently the ExportIconView --- src/IconPacks.Browser/Controls/SideBar.xaml | 1 + .../IcoExport/ExportIconView.xaml | 24 +++ .../IcoExport/ExportIconView.xaml.cs | 27 +++ .../IcoExport/ExportIconViewModel.cs | 14 ++ .../IcoExport/IconFactory.cs | 195 ++++++++++++++++++ .../ViewModels/IconPackViewModel.cs | 144 ++++++++++--- 6 files changed, 375 insertions(+), 30 deletions(-) create mode 100644 src/IconPacks.Browser/IcoExport/ExportIconView.xaml create mode 100644 src/IconPacks.Browser/IcoExport/ExportIconView.xaml.cs create mode 100644 src/IconPacks.Browser/IcoExport/ExportIconViewModel.cs create mode 100644 src/IconPacks.Browser/IcoExport/IconFactory.cs diff --git a/src/IconPacks.Browser/Controls/SideBar.xaml b/src/IconPacks.Browser/Controls/SideBar.xaml index a3f5199..dd43d05 100644 --- a/src/IconPacks.Browser/Controls/SideBar.xaml +++ b/src/IconPacks.Browser/Controls/SideBar.xaml @@ -240,6 +240,7 @@ + + - + diff --git a/src/IconPacks.Browser/IcoExport/ExportIconView.xaml.cs b/src/IconPacks.Browser/IcoExport/ExportIconView.xaml.cs index cd99ae4..5db798f 100644 --- a/src/IconPacks.Browser/IcoExport/ExportIconView.xaml.cs +++ b/src/IconPacks.Browser/IcoExport/ExportIconView.xaml.cs @@ -1,4 +1,5 @@ -using System; +using MahApps.Metro.Controls; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -17,11 +18,25 @@ namespace IconPacks.Browser.IcoExport /// /// Interaktionslogik für ExportIconView.xaml /// - public partial class ExportIconView : Window + public partial class ExportIconView : MetroWindow { public ExportIconView() { InitializeComponent(); + PreviewHolder.LayoutUpdated += PreviewHolder_LayoutUpdated; + } + + private void PreviewHolder_LayoutUpdated(object sender, EventArgs e) + { + //PreviewBorder.SetCurrentValue(Path.WidthProperty, PreviewHolder.Width); + //PreviewBorder.SetCurrentValue(Path.HeightProperty, PreviewHolder.Height); + //PreviewBorder.SetCurrentValue(Path.MarginProperty, PreviewHolder.Margin); + + } + + private void Slider_MouseDoubleClick(object sender, MouseButtonEventArgs e) + { + ((Slider)sender).SetCurrentValue(Slider.ValueProperty,0.0); } } } diff --git a/src/IconPacks.Browser/IcoExport/ExportIconViewModel.cs b/src/IconPacks.Browser/IcoExport/ExportIconViewModel.cs index cac4bb1..6a05eb0 100644 --- a/src/IconPacks.Browser/IcoExport/ExportIconViewModel.cs +++ b/src/IconPacks.Browser/IcoExport/ExportIconViewModel.cs @@ -1,14 +1,307 @@ -using IconPacks.Browser.ViewModels; +using IconPacks.Browser.Properties; +using IconPacks.Browser.ViewModels; using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Runtime; using System.Text; using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; +using static System.Net.Mime.MediaTypeNames; namespace IconPacks.Browser.IcoExport { - internal class ExportIconViewModel: ViewModelBase + internal class ExportIconViewModel : ViewModelBase { - public System.Drawing.Bitmap Preview { get; set; } ///Wip !!! + /// + /// Reference to the selected Icon. Backing Var + /// + private IconViewModel icon; + + /// + /// class new + /// + public ExportIconViewModel() + { + OkCommand = new SimpleCommand(x => OkExecute(x), (_) => true); + CancelCommand = new SimpleCommand((_) => CancelExecute(), (_) => true); + } + /// + /// Reference to the form. I know, not MVVM but simple :) + /// + public ExportIconView Frm { get; set; } + + /// + /// Reference to the selected Icon. + /// + public IconViewModel Icon + { + get => icon; set + { + if (Set(ref icon, value)) + { + this.OnPropertyChanged(nameof(RectGeometry)); + } + } + } + + /// + /// The border around the Icon + /// + public Geometry RectGeometry + { + get + { + Geometry rg = null; + if (IcoExportRectEnabled) + { + var Offset = ((256 - IcoExportRectSize) / 2) + (IcoExportPathStrokeThickness / 2); + rg = new RectangleGeometry(new System.Windows.Rect(Offset, Offset, Math.Max(IcoExportRectSize - IcoExportPathStrokeThickness, 2), Math.Max(IcoExportRectSize - IcoExportPathStrokeThickness, 2)), IcoExportRectRadius, IcoExportRectRadius); + } + + return rg; + } + } + + /// + /// MahIcon Translation + /// + public Transform IconTranslate + { + get + { + TransformGroup t = new TransformGroup(); + t.Children.Add(new RotateTransform(IcoExportIconRotate)); + t.Children.Add(new TranslateTransform(IcoExportIconTranslateX, IcoExportIconTranslateY)); + return t; + } + } + + /// + /// The forecolor of the mah-icon + /// + public Color IcoExportIconForeground + { + get => Settings.Default.IcoExportIconForeground; set + { + Settings.Default.IcoExportIconForeground = value; + this.OnPropertyChanged(nameof(IcoExportIconForeground)); + } + } + + /// + /// the backcolor of the mahicon on canvas + /// + public Color IcoExportIconBackground + { + get => Settings.Default.IcoExportIconBackground; set + { + Settings.Default.IcoExportIconBackground = value; + this.OnPropertyChanged(nameof(IcoExportIconBackground)); + this.OnPropertyChanged(nameof(IcoExportPathBackground)); + } + } + + /// + /// The size of the mahicon on canvas + /// + public int IcoExportIconSize + { + get => Settings.Default.IcoExportIconSize; set + { + Settings.Default.IcoExportIconSize = value; + this.OnPropertyChanged(nameof(IcoExportIconSize)); + } + } + + /// + /// Rotation of the mahicon + /// + public int IcoExportIconRotate + { + get => Settings.Default.IcoExportIconRotate; set + { + Settings.Default.IcoExportIconRotate = value; + this.OnPropertyChanged(nameof(IconTranslate)); + } + } + + /// + /// Translation of the mahicon + /// + public int IcoExportIconTranslateX + { + get => Settings.Default.IcoExportIconTranslateX; set + { + Settings.Default.IcoExportIconTranslateX = value; + this.OnPropertyChanged(nameof(IconTranslate)); + } + } + + /// + /// Translation of the mahicon + /// + public int IcoExportIconTranslateY + { + get => Settings.Default.IcoExportIconTranslateY; set + { + Settings.Default.IcoExportIconTranslateY = value; + this.OnPropertyChanged(nameof(IconTranslate)); + } + } + + /// + /// Color of the Background of the rect, when Path is off + /// + public Color IcoExportPathBackground + { + get + { + if (IcoExportRectEnabled) return Colors.Transparent; + return Settings.Default.IcoExportIconBackground; + } + } + + + + /// + /// Fill color of the rect + /// + public Color IcoExportPathFill + { + get => Settings.Default.IcoExportPathFill; set + { + Settings.Default.IcoExportPathFill = value; + this.OnPropertyChanged(nameof(IcoExportPathFill)); + } + } + + /// + /// The color of the path stroke + /// + public Color IcoExportPathStroke + { + get => Settings.Default.IcoExportPathStroke; set + { + Settings.Default.IcoExportPathStroke = value; + this.OnPropertyChanged(nameof(IcoExportPathStroke)); + this.OnPropertyChanged(nameof(RectGeometry)); + } + } + + /// + /// the stroke width of thge rect + /// + public int IcoExportPathStrokeThickness + { + get => Settings.Default.IcoExportPathStrokeThickness; set + { + Settings.Default.IcoExportPathStrokeThickness = value; + this.OnPropertyChanged(nameof(IcoExportPathStrokeThickness)); + this.OnPropertyChanged(nameof(RectGeometry)); + } + } + + /// + /// Size of the rect + /// + public int IcoExportRectSize + { + get => Settings.Default.IcoExportRectSize; set + { + Settings.Default.IcoExportRectSize = value; + this.OnPropertyChanged(nameof(RectGeometry)); + } + } + + /// + /// Border Radius of the Rect + /// + public int IcoExportRectRadius + { + get => Settings.Default.IcoExportRectRadius; set + { + Settings.Default.IcoExportRectRadius = value; + this.OnPropertyChanged(nameof(RectGeometry)); + } + } + + + + /// + /// Enable the rect + /// + public bool IcoExportRectEnabled + { + get => Settings.Default.IcoExportRectEnabled; set + { + Settings.Default.IcoExportRectEnabled = value; + this.OnPropertyChanged(nameof(RectGeometry)); + this.OnPropertyChanged(nameof(IcoExportPathBackground)); + } + } + + public ICommand OkCommand { get; } + + public ICommand CancelCommand { get; } + + public List IconBitmaps { get; set; } = new List(); + + private void OkExecute(object parameter) + { + if (parameter is Grid grid) + { + if (Settings.Default.IcoExport256) IconBitmaps.Add(RenderBitmap(grid, 256)); + if (Settings.Default.IcoExport180) IconBitmaps.Add(RenderBitmap(grid, 180)); + if (Settings.Default.IcoExport128) IconBitmaps.Add(RenderBitmap(grid, 128)); + if (Settings.Default.IcoExport96) IconBitmaps.Add(RenderBitmap(grid, 96)); + if (Settings.Default.IcoExport72) IconBitmaps.Add(RenderBitmap(grid, 72)); + if (Settings.Default.IcoExport64) IconBitmaps.Add(RenderBitmap(grid, 64)); + if (Settings.Default.IcoExport48) IconBitmaps.Add(RenderBitmap(grid, 48)); + if (Settings.Default.IcoExport32) IconBitmaps.Add(RenderBitmap(grid, 32)); + if (Settings.Default.IcoExport24) IconBitmaps.Add(RenderBitmap(grid, 24)); + if (Settings.Default.IcoExport16) IconBitmaps.Add(RenderBitmap(grid, 16)); + Frm.DialogResult = true; + } + } + + private System.Drawing.Bitmap RenderBitmap(Grid grid, double size) + { + grid.SetCurrentValue(Grid.RenderTransformProperty, new ScaleTransform(size / 256, size / 256)); + Canvas.SetLeft(grid, 0); + Canvas.SetTop(grid, 0); + grid.Measure(new Size(grid.Width, grid.Height)); + grid.Arrange(new Rect(new Size(grid.Width, grid.Height))); + grid.UpdateLayout(); + + var rtb = new RenderTargetBitmap( + (int)size, + (int)size, + 96, + 96, + PixelFormats.Pbgra32); + + + + rtb.Render(grid); + MemoryStream stream = new MemoryStream(); + BitmapEncoder encoder = new PngBitmapEncoder(); + encoder.Frames.Add(BitmapFrame.Create(rtb)); + encoder.Save(stream); + + return new System.Drawing.Bitmap(stream); + } + + private void CancelExecute() + { + Frm.DialogResult = false; + } + } } diff --git a/src/IconPacks.Browser/IconPacks.Browser.csproj b/src/IconPacks.Browser/IconPacks.Browser.csproj index 52a5f5b..f1e77c0 100644 --- a/src/IconPacks.Browser/IconPacks.Browser.csproj +++ b/src/IconPacks.Browser/IconPacks.Browser.csproj @@ -20,12 +20,12 @@ + all runtime; build; native; contentfiles; analyzers - @@ -41,6 +41,11 @@ <_SettingsFiles Remove="Properties\Settings.settings" /> + + True + True + Settings.settings + PreserveNewest @@ -71,6 +76,10 @@ PreserveNewest + + SettingsSingleFileGenerator + Settings.Designer.cs + diff --git a/src/IconPacks.Browser/Properties/Settings.Designer.cs b/src/IconPacks.Browser/Properties/Settings.Designer.cs index 883a44a..c3c0752 100644 --- a/src/IconPacks.Browser/Properties/Settings.Designer.cs +++ b/src/IconPacks.Browser/Properties/Settings.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. // //------------------------------------------------------------------------------ @@ -12,8 +12,8 @@ namespace IconPacks.Browser.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")] - public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -106,5 +106,269 @@ public string ExportTemplatesDir { this["ExportTemplatesDir"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("#00FFFFFF")] + public global::System.Windows.Media.Color IcoExportIconBackground { + get { + return ((global::System.Windows.Media.Color)(this["IcoExportIconBackground"])); + } + set { + this["IcoExportIconBackground"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("#FF000000")] + public global::System.Windows.Media.Color IcoExportIconForeground { + get { + return ((global::System.Windows.Media.Color)(this["IcoExportIconForeground"])); + } + set { + this["IcoExportIconForeground"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("#FFFFFFFF")] + public global::System.Windows.Media.Color IcoExportPathFill { + get { + return ((global::System.Windows.Media.Color)(this["IcoExportPathFill"])); + } + set { + this["IcoExportPathFill"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("#FF000000")] + public global::System.Windows.Media.Color IcoExportPathStroke { + get { + return ((global::System.Windows.Media.Color)(this["IcoExportPathStroke"])); + } + set { + this["IcoExportPathStroke"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("256")] + public int IcoExportIconSize { + get { + return ((int)(this["IcoExportIconSize"])); + } + set { + this["IcoExportIconSize"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("256")] + public int IcoExportRectSize { + get { + return ((int)(this["IcoExportRectSize"])); + } + set { + this["IcoExportRectSize"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("20")] + public int IcoExportRectRadius { + get { + return ((int)(this["IcoExportRectRadius"])); + } + set { + this["IcoExportRectRadius"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("2")] + public int IcoExportPathStrokeThickness { + get { + return ((int)(this["IcoExportPathStrokeThickness"])); + } + set { + this["IcoExportPathStrokeThickness"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool IcoExportRectEnabled { + get { + return ((bool)(this["IcoExportRectEnabled"])); + } + set { + this["IcoExportRectEnabled"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0")] + public int IcoExportIconRotate { + get { + return ((int)(this["IcoExportIconRotate"])); + } + set { + this["IcoExportIconRotate"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0")] + public int IcoExportIconTranslateX { + get { + return ((int)(this["IcoExportIconTranslateX"])); + } + set { + this["IcoExportIconTranslateX"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0")] + public int IcoExportIconTranslateY { + get { + return ((int)(this["IcoExportIconTranslateY"])); + } + set { + this["IcoExportIconTranslateY"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool IcoExport16 { + get { + return ((bool)(this["IcoExport16"])); + } + set { + this["IcoExport16"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool IcoExport24 { + get { + return ((bool)(this["IcoExport24"])); + } + set { + this["IcoExport24"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool IcoExport32 { + get { + return ((bool)(this["IcoExport32"])); + } + set { + this["IcoExport32"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool IcoExport48 { + get { + return ((bool)(this["IcoExport48"])); + } + set { + this["IcoExport48"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool IcoExport64 { + get { + return ((bool)(this["IcoExport64"])); + } + set { + this["IcoExport64"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool IcoExport72 { + get { + return ((bool)(this["IcoExport72"])); + } + set { + this["IcoExport72"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool IcoExport96 { + get { + return ((bool)(this["IcoExport96"])); + } + set { + this["IcoExport96"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool IcoExport128 { + get { + return ((bool)(this["IcoExport128"])); + } + set { + this["IcoExport128"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool IcoExport180 { + get { + return ((bool)(this["IcoExport180"])); + } + set { + this["IcoExport180"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool IcoExport256 { + get { + return ((bool)(this["IcoExport256"])); + } + set { + this["IcoExport256"] = value; + } + } } } diff --git a/src/IconPacks.Browser/Properties/Settings.cs b/src/IconPacks.Browser/Properties/Settings.cs index 64fc54e..a1fe6b6 100644 --- a/src/IconPacks.Browser/Properties/Settings.cs +++ b/src/IconPacks.Browser/Properties/Settings.cs @@ -1,12 +1,12 @@ namespace IconPacks.Browser.Properties { - - + + // This class allows you to handle specific events on the settings class: // The SettingChanging event is raised before a setting's value is changed. // The PropertyChanged event is raised after a setting's value is changed. // The SettingsLoaded event is raised after the setting values are loaded. // The SettingsSaving event is raised before the setting values are saved. - public sealed partial class Settings { + internal sealed partial class Settings { public Settings() { // // To add event handlers for saving and changing settings, uncomment the lines below: diff --git a/src/IconPacks.Browser/Properties/Settings.settings b/src/IconPacks.Browser/Properties/Settings.settings index 8810e04..8d58463 100644 --- a/src/IconPacks.Browser/Properties/Settings.settings +++ b/src/IconPacks.Browser/Properties/Settings.settings @@ -23,5 +23,71 @@ + + #00FFFFFF + + + #FF000000 + + + #FFFFFFFF + + + #FF000000 + + + 256 + + + 256 + + + 20 + + + 2 + + + True + + + 0 + + + 0 + + + 0 + + + True + + + False + + + True + + + True + + + False + + + False + + + False + + + False + + + False + + + True + \ No newline at end of file diff --git a/src/IconPacks.Browser/ViewModels/IconPackViewModel.cs b/src/IconPacks.Browser/ViewModels/IconPackViewModel.cs index 402e03d..e2ecddc 100644 --- a/src/IconPacks.Browser/ViewModels/IconPackViewModel.cs +++ b/src/IconPacks.Browser/ViewModels/IconPackViewModel.cs @@ -74,6 +74,11 @@ public IconPackViewModel(MainViewModel mainViewModel, string caption, Type[] enu this.LoadAllEnumsAsync(enumTypes, packTypes).SafeFireAndForget(); } + //For Design Mode + public IconPackViewModel() + { + } + private async Task LoadEnumsAsync(Type enumType, Type packType) { var collection = await Task.Run(() => GetIcons(enumType, packType).OrderBy(i => i.Name, StringComparer.InvariantCultureIgnoreCase).ToList()); @@ -410,53 +415,41 @@ private async void SaveAsIconExecute() try { - var fileSaveDialog = new SaveFileDialog() + if (SelectedIcon is IconViewModel icon) { - AddExtension = true, - FileName = $"{SelectedIcon.IconPackName}-{SelectedIcon.Name}", - Filter = "Ico-File (*.ico)|*.ico", - OverwritePrompt = true - }; - + + var IcoOptionsView = new ExportIconView(); + var IcoOptionViewModel = new ExportIconViewModel() { Frm = IcoOptionsView, Icon = icon }; + IcoOptionsView.DataContext = IcoOptionViewModel; + if (IcoOptionsView.ShowDialog() == true && IcoOptionViewModel.IconBitmaps.Count != 0) + { - if (fileSaveDialog.ShowDialog() == true && SelectedIcon is IconViewModel icon) - { - var background = new SolidColorBrush(Settings.Default.IconBackground); + var fileSaveDialog = new SaveFileDialog() + { + AddExtension = true, + FileName = $"{SelectedIcon.IconPackName}-{SelectedIcon.Name}", + Filter = "Ico-File (*.ico)|*.ico", + OverwritePrompt = true + }; - var frm = new ExportIconView(); - var vm = new ExportIconViewModel(); - vm.Preview = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 200)) ; - frm.DataContext = vm; - if (frm.ShowDialog() == true) - { - using (var png16 = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 16))) - using (var png24 = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 24))) - using (var png32 = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 32))) - using (var png48 = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 48))) - using (var png64 = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 64))) - using (var png72 = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 72))) - using (var png96 = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 96))) - using (var png128 = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 128))) - using (var png180 = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 180))) - using (var png256 = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(GetBitmapStream(new PngBitmapEncoder(), icon, background, 256))) - using (var stream = new System.IO.FileStream(fileSaveDialog.FileName, System.IO.FileMode.Create)) + if (fileSaveDialog.ShowDialog() == true) { - List l = new List(); - if (png16 != null) l.Add(png16); - if (png24 != null) l.Add(png24); - if (png32 != null) l.Add(png32); - if (png48 != null) l.Add(png48); - if (png64 != null) l.Add(png64); - if (png72 != null) l.Add(png72); - if (png96 != null) l.Add(png96); - if (png128 != null) l.Add(png128); - if (png180 != null) l.Add(png180); - if (png256 != null) l.Add(png256); - IconFactory.SavePngsAsIcon(l.ToArray(), stream); + + + + using (var stream = new System.IO.FileStream(fileSaveDialog.FileName, System.IO.FileMode.Create)) + { + + IconFactory.SavePngsAsIcon(IcoOptionViewModel.IconBitmaps.ToArray(), stream); + foreach (var bm in IcoOptionViewModel.IconBitmaps) + { + bm.Dispose(); + } + } } - } + } } } catch (Exception e) @@ -491,14 +484,36 @@ private async void SaveAsBitmapExecute(BitmapEncoder encoder) if (fileSaveDialog.ShowDialog() == true && SelectedIcon is IconViewModel icon) { + var canvas = new Canvas + { + Width = Settings.Default.IconPreviewSize, + Height = Settings.Default.IconPreviewSize, + Background = new SolidColorBrush(Settings.Default.IconBackground) + }; + var packIconControl = new PackIconControl(); + packIconControl.BeginInit(); + packIconControl.Kind = icon.Value as Enum; + packIconControl.Width = Settings.Default.IconPreviewSize; + packIconControl.Height = Settings.Default.IconPreviewSize; + packIconControl.Foreground = new SolidColorBrush(Settings.Default.IconForeground); - using var fileStream = new System.IO.FileStream(fileSaveDialog.FileName, System.IO.FileMode.Create); - using var memstream = GetBitmapStream(encoder, icon, new SolidColorBrush(Settings.Default.IconBackground), Settings.Default.IconPreviewSize); - { - memstream.WriteTo(fileStream); - } + packIconControl.EndInit(); + packIconControl.ApplyTemplate(); + + canvas.Children.Add(packIconControl); + + var size = new Size(Settings.Default.IconPreviewSize, Settings.Default.IconPreviewSize); + canvas.Measure(size); + canvas.Arrange(new Rect(size)); + + var renderTargetBitmap = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Pbgra32); + renderTargetBitmap.Render(canvas); + encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); + + using var fileStream = new IO.FileStream(fileSaveDialog.FileName, IO.FileMode.Create); + encoder.Save(fileStream); } } catch (Exception e) @@ -508,45 +523,8 @@ private async void SaveAsBitmapExecute(BitmapEncoder encoder) await progress.CloseAsync(); } - private System.IO.MemoryStream GetBitmapStream(BitmapEncoder encoder, IconViewModel icon, System.Windows.Media.Brush background, double width) - { - var canvas = new Canvas - { - Width = width, - Height = width, - Background = background - }; - - var packIconControl = new PackIconControl(); - packIconControl.BeginInit(); - packIconControl.Kind = icon.Value as Enum; - packIconControl.Width = width; - packIconControl.Height = width; - packIconControl.Foreground = new SolidColorBrush(Settings.Default.IconForeground); - - packIconControl.EndInit(); - packIconControl.ApplyTemplate(); - - canvas.Children.Add(packIconControl); - - var size = new System.Windows.Size(width, width); - canvas.Measure(size); - canvas.Arrange(new Rect(size)); - - var renderTargetBitmap = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Pbgra32); - renderTargetBitmap.Render(canvas); - - encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); - MemoryStream mem = new MemoryStream(); - encoder.Save(mem); - mem.Seek(0, SeekOrigin.Begin); - return mem; - } - } - - public interface IIconViewModel { string Name { get; set; }