diff --git a/src/App/ModernWpfPlayground.csproj b/src/App/ModernWpfPlayground.csproj index ffbeb67..752eec0 100644 --- a/src/App/ModernWpfPlayground.csproj +++ b/src/App/ModernWpfPlayground.csproj @@ -14,9 +14,9 @@ - - - + + + diff --git a/src/App/Types/AccentColors.cs b/src/App/Types/AccentColors.cs index b4215aa..7b64317 100644 --- a/src/App/Types/AccentColors.cs +++ b/src/App/Types/AccentColors.cs @@ -1,30 +1,29 @@ using System; using System.Windows.Media; -namespace ModernWpfPlayground.Types -{ - public enum AccentColors - { - Green, - Yellow, - Blue, - Purple, - Red - } +namespace ModernWpfPlayground.Types; - public static class AccentColorExtension +public enum AccentColors +{ + Green, + Yellow, + Blue, + Purple, + Red +} + +public static class AccentColorExtension +{ + public static Color ToWindowsColor(this AccentColors accentColor) { - public static Color ToWindowsColor(this AccentColors accentColor) + return accentColor switch { - return accentColor switch - { - AccentColors.Green => Color.FromRgb(0, 86, 76), - AccentColors.Yellow => Color.FromRgb(164, 144, 0), - AccentColors.Blue => Color.FromRgb(0, 120, 215), - AccentColors.Purple => Color.FromRgb(104, 33, 122), - AccentColors.Red => Color.FromRgb(183, 71, 42), - _ => throw new ArgumentOutOfRangeException(nameof(accentColor), accentColor, null) - }; - } + AccentColors.Green => Color.FromRgb(0, 86, 76), + AccentColors.Yellow => Color.FromRgb(164, 144, 0), + AccentColors.Blue => Color.FromRgb(0, 120, 215), + AccentColors.Purple => Color.FromRgb(104, 33, 122), + AccentColors.Red => Color.FromRgb(183, 71, 42), + _ => throw new ArgumentOutOfRangeException(nameof(accentColor), accentColor, null) + }; } } \ No newline at end of file diff --git a/src/Controls/PropertyPresenter/EnumToItemSourceConverter.cs b/src/Controls/PropertyPresenter/EnumToItemSourceConverter.cs index e7b5cce..e3e8973 100644 --- a/src/Controls/PropertyPresenter/EnumToItemSourceConverter.cs +++ b/src/Controls/PropertyPresenter/EnumToItemSourceConverter.cs @@ -6,44 +6,43 @@ using System.Linq; using System.Windows.Data; using System.Windows.Markup; -namespace Controls +namespace Controls; + +/// +/// Converts enums to a List with KeyValuePairs. +/// +public class EnumToItemSourceConverter : MarkupExtension, IValueConverter { - /// - /// Converts enums to a List with KeyValuePairs. - /// - public class EnumToItemSourceConverter : MarkupExtension, IValueConverter + private static EnumToItemSourceConverter? _converter; + + object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) { - private static EnumToItemSourceConverter? _converter; - - object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value is not Enum) return Binding.DoNothing; - return (from object enumValue in Enum.GetValues(value.GetType()) - select new KeyValuePair(GetDescription(enumValue), enumValue)).ToList(); - } - - /// - /// Returns the content of a description attribute of an enum. - /// - /// - /// - private static string GetDescription(object value) - { - if (value is not Enum enumValue) return string.Empty; - var descriptionAttribute = enumValue.GetType() - .GetField(enumValue.ToString())? - .GetCustomAttributes(false) - .OfType() - .FirstOrDefault(); - - return descriptionAttribute?.Description ?? value.ToString() ?? string.Empty; - } - - object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - return Binding.DoNothing; - } - - public override object ProvideValue(IServiceProvider serviceProvider) => _converter ??= new EnumToItemSourceConverter(); + if (value is not Enum) return Binding.DoNothing; + return (from object enumValue in Enum.GetValues(value.GetType()) + select new KeyValuePair(GetDescription(enumValue), enumValue)).ToList(); } + + /// + /// Returns the content of a description attribute of an enum. + /// + /// + /// + private static string GetDescription(object value) + { + if (value is not Enum enumValue) return string.Empty; + var descriptionAttribute = enumValue.GetType() + .GetField(enumValue.ToString())? + .GetCustomAttributes(false) + .OfType() + .FirstOrDefault(); + + return descriptionAttribute?.Description ?? value.ToString() ?? string.Empty; + } + + object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return Binding.DoNothing; + } + + public override object ProvideValue(IServiceProvider serviceProvider) => _converter ??= new EnumToItemSourceConverter(); } \ No newline at end of file diff --git a/src/Controls/PropertyPresenter/MagicSymbolControl.cs b/src/Controls/PropertyPresenter/MagicSymbolControl.cs index fde52df..069c006 100644 --- a/src/Controls/PropertyPresenter/MagicSymbolControl.cs +++ b/src/Controls/PropertyPresenter/MagicSymbolControl.cs @@ -2,42 +2,41 @@ using System.Windows.Controls; using System.Windows.Markup; -namespace Controls +namespace Controls; + +/// +/// Interaction logic for +/// +[ContentProperty(nameof(Symbol))] +public class MagicSymbolControl : ContentControl { /// - /// Interaction logic for + /// Dependency property for property /// - [ContentProperty(nameof(Symbol))] - public class MagicSymbolControl : ContentControl + public static readonly DependencyProperty SymbolProperty = DependencyProperty.Register(nameof(Symbol), typeof(object), typeof(MagicSymbolControl), new PropertyMetadata(default, PropertyChangedCallback)); + + private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { - /// - /// Dependency property for property - /// - public static readonly DependencyProperty SymbolProperty = DependencyProperty.Register(nameof(Symbol), typeof(object), typeof(MagicSymbolControl), new PropertyMetadata(default, PropertyChangedCallback)); - - private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + if (d is MagicSymbolControl magic) { - if (d is MagicSymbolControl magic) - { - magic.Content = MagicSymbolConverter.ConvertToFrameworkElement(e.NewValue); - } - } - - /// - /// Symbol to show - /// - public object Symbol - { - get => GetValue(SymbolProperty); - set => SetValue(SymbolProperty, value); - } - - /// - /// Creates a new instance of - /// - public MagicSymbolControl() - { - Focusable = false; + magic.Content = MagicSymbolConverter.ConvertToFrameworkElement(e.NewValue); } } + + /// + /// Symbol to show + /// + public object Symbol + { + get => GetValue(SymbolProperty); + set => SetValue(SymbolProperty, value); + } + + /// + /// Creates a new instance of + /// + public MagicSymbolControl() + { + Focusable = false; + } } \ No newline at end of file diff --git a/src/Controls/PropertyPresenter/MagicSymbolConverter.cs b/src/Controls/PropertyPresenter/MagicSymbolConverter.cs index acffbc1..3b7d77c 100644 --- a/src/Controls/PropertyPresenter/MagicSymbolConverter.cs +++ b/src/Controls/PropertyPresenter/MagicSymbolConverter.cs @@ -8,145 +8,144 @@ using System.Windows.Data; using System.Windows.Documents; using System.Windows.Media; -namespace Controls +namespace Controls; + +/// +/// Magically converts a text to +/// +[ValueConversion(typeof(string), typeof(FrameworkElement))] +public class MagicSymbolConverter : IValueConverter { - /// - /// Magically converts a text to - /// - [ValueConversion(typeof(string), typeof(FrameworkElement))] - public class MagicSymbolConverter : IValueConverter + private const string NoParseKeyword = "noParse:"; + private const string PathKeyword = "path:"; + private const string DynResKeyword = "dynRes:"; + + /// + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - private const string NoParseKeyword = "noParse:"; - private const string PathKeyword = "path:"; - private const string DynResKeyword = "dynRes:"; - - /// - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return ConvertToFrameworkElement(value); - } - - /// - /// Convert string to Framework element. - /// - /// - /// - public static object ConvertToFrameworkElement(object value) - { - var data = value as string; - if (string.IsNullOrWhiteSpace(data)) return value; //maybe not a string. eventually something else. - - if (data.StartsWith(NoParseKeyword, StringComparison.Ordinal)) return data[NoParseKeyword.Length..]; - - if (data.StartsWith(PathKeyword, StringComparison.Ordinal)) - { - var path = data[PathKeyword.Length..]; - var icon = ObjectImageConverter.GetIcon(Geometry.Parse(path), Brushes.Black); - return new Image - { - Source = icon, - HorizontalAlignment = HorizontalAlignment.Right, - VerticalAlignment = VerticalAlignment.Center, - Height = 16 - }; - } - - if (data.StartsWith(DynResKeyword, StringComparison.Ordinal)) - { - var resourceKey = data[DynResKeyword.Length..]; - //get icon from resource dictionary - return new Image - { - Source = Application.Current.FindResource(resourceKey) as ImageSource, - HorizontalAlignment = HorizontalAlignment.Right, - VerticalAlignment = VerticalAlignment.Center, - Height = 16 - }; - } - - var textComponents = ParseText(data); - return CreateTextBlock(textComponents); - } - - private static TextBlock CreateTextBlock(IEnumerable textComponents) - { - //create text block - var block = new TextBlock(); - foreach (var tc in textComponents) - { - var run = new Run(tc.Text) {FontFamily = new FontFamily("Palatino Linotype"), FontSize = 16}; - switch (tc.Style) - { - case BaselineAlignment.Subscript: - run.BaselineAlignment = BaselineAlignment.Subscript; - run.FontSize = 12; - break; - case BaselineAlignment.Superscript: - run.BaselineAlignment = BaselineAlignment.Superscript; - run.FontSize = 12; - break; - } - - block.Inlines.Add(run); - } - - block.HorizontalAlignment = HorizontalAlignment.Right; - block.VerticalAlignment = VerticalAlignment.Center; - return block; - } - - private static IEnumerable ParseText(string data) - { - //parse text - var textComponents = new List(); - var alignment = BaselineAlignment.Baseline; - var snippet = new StringBuilder(); - foreach (var c in data) - { - switch (c) - { - case '~': - if (snippet.Length > 0) - { - var comp = new TextComponent(snippet.ToString(), alignment); - textComponents.Add(comp); - snippet.Clear(); - } - - alignment = alignment == BaselineAlignment.Subscript - ? BaselineAlignment.Baseline - : BaselineAlignment.Subscript; - break; - case '^': - if (snippet.Length > 0) - { - var comp = new TextComponent(snippet.ToString(), alignment); - textComponents.Add(comp); - snippet.Clear(); - } - - alignment = alignment == BaselineAlignment.Superscript - ? BaselineAlignment.Baseline - : BaselineAlignment.Superscript; - break; - default: - snippet.Append(c); - break; - } - } - - if (snippet.Length > 0) - { - var comp = new TextComponent(snippet.ToString(), alignment); - textComponents.Add(comp); - snippet.Clear(); - } - - return textComponents; - } - - /// - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - => Binding.DoNothing; + return ConvertToFrameworkElement(value); } + + /// + /// Convert string to Framework element. + /// + /// + /// + public static object ConvertToFrameworkElement(object value) + { + var data = value as string; + if (string.IsNullOrWhiteSpace(data)) return value; //maybe not a string. eventually something else. + + if (data.StartsWith(NoParseKeyword, StringComparison.Ordinal)) return data[NoParseKeyword.Length..]; + + if (data.StartsWith(PathKeyword, StringComparison.Ordinal)) + { + var path = data[PathKeyword.Length..]; + var icon = ObjectImageConverter.GetIcon(Geometry.Parse(path), Brushes.Black); + return new Image + { + Source = icon, + HorizontalAlignment = HorizontalAlignment.Right, + VerticalAlignment = VerticalAlignment.Center, + Height = 16 + }; + } + + if (data.StartsWith(DynResKeyword, StringComparison.Ordinal)) + { + var resourceKey = data[DynResKeyword.Length..]; + //get icon from resource dictionary + return new Image + { + Source = Application.Current.FindResource(resourceKey) as ImageSource, + HorizontalAlignment = HorizontalAlignment.Right, + VerticalAlignment = VerticalAlignment.Center, + Height = 16 + }; + } + + var textComponents = ParseText(data); + return CreateTextBlock(textComponents); + } + + private static TextBlock CreateTextBlock(IEnumerable textComponents) + { + //create text block + var block = new TextBlock(); + foreach (var tc in textComponents) + { + var run = new Run(tc.Text) {FontFamily = new FontFamily("Palatino Linotype"), FontSize = 16}; + switch (tc.Style) + { + case BaselineAlignment.Subscript: + run.BaselineAlignment = BaselineAlignment.Subscript; + run.FontSize = 12; + break; + case BaselineAlignment.Superscript: + run.BaselineAlignment = BaselineAlignment.Superscript; + run.FontSize = 12; + break; + } + + block.Inlines.Add(run); + } + + block.HorizontalAlignment = HorizontalAlignment.Right; + block.VerticalAlignment = VerticalAlignment.Center; + return block; + } + + private static IEnumerable ParseText(string data) + { + //parse text + var textComponents = new List(); + var alignment = BaselineAlignment.Baseline; + var snippet = new StringBuilder(); + foreach (var c in data) + { + switch (c) + { + case '~': + if (snippet.Length > 0) + { + var comp = new TextComponent(snippet.ToString(), alignment); + textComponents.Add(comp); + snippet.Clear(); + } + + alignment = alignment == BaselineAlignment.Subscript + ? BaselineAlignment.Baseline + : BaselineAlignment.Subscript; + break; + case '^': + if (snippet.Length > 0) + { + var comp = new TextComponent(snippet.ToString(), alignment); + textComponents.Add(comp); + snippet.Clear(); + } + + alignment = alignment == BaselineAlignment.Superscript + ? BaselineAlignment.Baseline + : BaselineAlignment.Superscript; + break; + default: + snippet.Append(c); + break; + } + } + + if (snippet.Length > 0) + { + var comp = new TextComponent(snippet.ToString(), alignment); + textComponents.Add(comp); + snippet.Clear(); + } + + return textComponents; + } + + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + => Binding.DoNothing; } \ No newline at end of file diff --git a/src/Controls/PropertyPresenter/PropertyDataTemplateSelector.cs b/src/Controls/PropertyPresenter/PropertyDataTemplateSelector.cs index c68352f..b708194 100644 --- a/src/Controls/PropertyPresenter/PropertyDataTemplateSelector.cs +++ b/src/Controls/PropertyPresenter/PropertyDataTemplateSelector.cs @@ -2,38 +2,37 @@ using System.Windows; using System.Windows.Controls; -namespace Controls +namespace Controls; + +/// +/// Selects the right template on base of value-type. +/// +public class PropertyDataTemplateSelector : DataTemplateSelector { /// - /// Selects the right template on base of value-type. + /// Default data template. (currently Textbox) /// - public class PropertyDataTemplateSelector : DataTemplateSelector + public DataTemplate? DefaultDataTemplate { private get; set; } + + /// + /// Data template for boolean. (currently Checkbox) + /// + public DataTemplate? BooleanDataTemplate { private get; set; } + + /// + /// Data template for enums. (currently Combobox) + /// + public DataTemplate? EnumComboBoxDataTemplate { private get; set; } + + /// + public override DataTemplate? SelectTemplate(object item, DependencyObject container) { - /// - /// Default data template. (currently Textbox) - /// - public DataTemplate? DefaultDataTemplate { private get; set; } - - /// - /// Data template for boolean. (currently Checkbox) - /// - public DataTemplate? BooleanDataTemplate { private get; set; } - - /// - /// Data template for enums. (currently Combobox) - /// - public DataTemplate? EnumComboBoxDataTemplate { private get; set; } - - /// - public override DataTemplate? SelectTemplate(object item, DependencyObject container) + return item switch { - return item switch - { - bool _ => BooleanDataTemplate, - Enum _ => EnumComboBoxDataTemplate, - UIElement _ => null, - _ => DefaultDataTemplate - }; - } + bool _ => BooleanDataTemplate, + Enum _ => EnumComboBoxDataTemplate, + UIElement _ => null, + _ => DefaultDataTemplate + }; } } \ No newline at end of file diff --git a/src/Controls/PropertyPresenter/PropertyPresenter.xaml.cs b/src/Controls/PropertyPresenter/PropertyPresenter.xaml.cs index 683b94f..f1bb884 100644 --- a/src/Controls/PropertyPresenter/PropertyPresenter.xaml.cs +++ b/src/Controls/PropertyPresenter/PropertyPresenter.xaml.cs @@ -3,179 +3,178 @@ using System.Windows.Controls; using System.Windows.Input; using System.Windows.Markup; -namespace Controls +namespace Controls; + +/// +/// +/// Interaction logic for PropertyPresenter.xaml +/// +[ContentProperty(nameof(Value))] +public sealed partial class PropertyPresenter { - /// /// - /// Interaction logic for PropertyPresenter.xaml + /// Button alignment property. /// - [ContentProperty(nameof(Value))] - public sealed partial class PropertyPresenter + public static readonly DependencyProperty ButtonAlignmentProperty = DependencyProperty.Register(nameof(ButtonAlignment), typeof(Dock), typeof(PropertyPresenter), new PropertyMetadata(Dock.Right)); + + /// + /// Content of the command property. + /// + public static readonly DependencyProperty CommandContentProperty = DependencyProperty.Register(nameof(CommandContent), typeof(object), typeof(PropertyPresenter), new PropertyMetadata("...")); + + /// + /// Command Parameter property + /// + public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(nameof(CommandParameter), typeof(object), typeof(PropertyPresenter), new PropertyMetadata(default(object))); + + /// + /// Command property + /// + public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(PropertyPresenter), new PropertyMetadata(default(ICommand))); + + /// + /// is checked property. + /// + public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register(nameof(IsChecked), typeof(bool?), typeof(PropertyPresenter), new FrameworkPropertyMetadata(default(bool?), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); + + /// + /// Is readonly property + /// + public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register(nameof(IsReadOnly), typeof(bool), typeof(PropertyPresenter), new PropertyMetadata(default(bool))); + + /// + /// Label property + /// + public static readonly DependencyProperty LabelProperty = DependencyProperty.Register(nameof(Label), typeof(string), typeof(PropertyPresenter), new PropertyMetadata(default(string))); + + /// + /// label width property. + /// + public static readonly DependencyProperty LabelWidthProperty = DependencyProperty.Register(nameof(LabelWidth), typeof(double), typeof(PropertyPresenter), new PropertyMetadata(150.0)); + + /// + /// Symbol Property + /// + public static readonly DependencyProperty SymbolProperty = DependencyProperty.Register(nameof(Symbol), typeof(object), typeof(PropertyPresenter), new PropertyMetadata(default(object))); + + /// + /// Value Property + /// + public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(object), typeof(PropertyPresenter), new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); + + /// + /// Watermark Property + /// + public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register(nameof(Watermark), typeof(string), typeof(PropertyPresenter), new FrameworkPropertyMetadata(default(string))); + + /// + public PropertyPresenter() { - /// - /// Button alignment property. - /// - public static readonly DependencyProperty ButtonAlignmentProperty = DependencyProperty.Register(nameof(ButtonAlignment), typeof(Dock), typeof(PropertyPresenter), new PropertyMetadata(Dock.Right)); + InitializeComponent(); + } - /// - /// Content of the command property. - /// - public static readonly DependencyProperty CommandContentProperty = DependencyProperty.Register(nameof(CommandContent), typeof(object), typeof(PropertyPresenter), new PropertyMetadata("...")); + /// + /// Button alignment. + /// + public Dock ButtonAlignment + { + get => (Dock)GetValue(ButtonAlignmentProperty); + set => SetValue(ButtonAlignmentProperty, value); + } - /// - /// Command Parameter property - /// - public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(nameof(CommandParameter), typeof(object), typeof(PropertyPresenter), new PropertyMetadata(default(object))); + /// + /// Command. + /// + public ICommand? Command + { + get => (ICommand)GetValue(CommandProperty); + set => SetValue(CommandProperty, value); + } - /// - /// Command property - /// - public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(PropertyPresenter), new PropertyMetadata(default(ICommand))); + /// + /// Command content. + /// + public object? CommandContent + { + get => GetValue(CommandContentProperty); + set => SetValue(CommandContentProperty, value); + } - /// - /// is checked property. - /// - public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register(nameof(IsChecked), typeof(bool?), typeof(PropertyPresenter), new FrameworkPropertyMetadata(default(bool?), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); + /// + /// Command parameter. + /// + public object? CommandParameter + { + get => GetValue(CommandParameterProperty); + set => SetValue(CommandParameterProperty, value); + } - /// - /// Is readonly property - /// - public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register(nameof(IsReadOnly), typeof(bool), typeof(PropertyPresenter), new PropertyMetadata(default(bool))); + /// + /// IsChecked. + /// + public bool? IsChecked + { + get => (bool?)GetValue(IsCheckedProperty); + set => SetValue(IsCheckedProperty, value); + } - /// - /// Label property - /// - public static readonly DependencyProperty LabelProperty = DependencyProperty.Register(nameof(Label), typeof(string), typeof(PropertyPresenter), new PropertyMetadata(default(string))); + /// + /// IsReadOnly + /// + public bool IsReadOnly + { + get => (bool)GetValue(IsReadOnlyProperty); + set => SetValue(IsReadOnlyProperty, value); + } - /// - /// label width property. - /// - public static readonly DependencyProperty LabelWidthProperty = DependencyProperty.Register(nameof(LabelWidth), typeof(double), typeof(PropertyPresenter), new PropertyMetadata(150.0)); + /// + /// Label. + /// + public string? Label + { + get => (string)GetValue(LabelProperty); + set => SetValue(LabelProperty, value); + } - /// - /// Symbol Property - /// - public static readonly DependencyProperty SymbolProperty = DependencyProperty.Register(nameof(Symbol), typeof(object), typeof(PropertyPresenter), new PropertyMetadata(default(object))); + /// + /// Label width. + /// + public double LabelWidth + { + get => (double)GetValue(LabelWidthProperty); + set => SetValue(LabelWidthProperty, value); + } - /// - /// Value Property - /// - public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(object), typeof(PropertyPresenter), new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); + /// + /// Symbol. + /// + public object? Symbol + { + get => GetValue(SymbolProperty); + set => SetValue(SymbolProperty, value); + } - /// - /// Watermark Property - /// - public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register(nameof(Watermark), typeof(string), typeof(PropertyPresenter), new FrameworkPropertyMetadata(default(string))); + /// + /// Value. + /// + public object? Value + { + get => GetValue(ValueProperty); + set => SetValue(ValueProperty, value); + } - /// - public PropertyPresenter() - { - InitializeComponent(); - } + /// + /// Watermark. + /// + public string Watermark + { + get => (string)GetValue(WatermarkProperty); + set => SetValue(WatermarkProperty, value); + } - /// - /// Button alignment. - /// - public Dock ButtonAlignment - { - get => (Dock)GetValue(ButtonAlignmentProperty); - set => SetValue(ButtonAlignmentProperty, value); - } - - /// - /// Command. - /// - public ICommand? Command - { - get => (ICommand)GetValue(CommandProperty); - set => SetValue(CommandProperty, value); - } - - /// - /// Command content. - /// - public object? CommandContent - { - get => GetValue(CommandContentProperty); - set => SetValue(CommandContentProperty, value); - } - - /// - /// Command parameter. - /// - public object? CommandParameter - { - get => GetValue(CommandParameterProperty); - set => SetValue(CommandParameterProperty, value); - } - - /// - /// IsChecked. - /// - public bool? IsChecked - { - get => (bool?)GetValue(IsCheckedProperty); - set => SetValue(IsCheckedProperty, value); - } - - /// - /// IsReadOnly - /// - public bool IsReadOnly - { - get => (bool)GetValue(IsReadOnlyProperty); - set => SetValue(IsReadOnlyProperty, value); - } - - /// - /// Label. - /// - public string? Label - { - get => (string)GetValue(LabelProperty); - set => SetValue(LabelProperty, value); - } - - /// - /// Label width. - /// - public double LabelWidth - { - get => (double)GetValue(LabelWidthProperty); - set => SetValue(LabelWidthProperty, value); - } - - /// - /// Symbol. - /// - public object? Symbol - { - get => GetValue(SymbolProperty); - set => SetValue(SymbolProperty, value); - } - - /// - /// Value. - /// - public object? Value - { - get => GetValue(ValueProperty); - set => SetValue(ValueProperty, value); - } - - /// - /// Watermark. - /// - public string Watermark - { - get => (string)GetValue(WatermarkProperty); - set => SetValue(WatermarkProperty, value); - } - - /// - public override string ToString() - { - return $"{base.ToString()} {Value}"; - } + /// + public override string ToString() + { + return $"{base.ToString()} {Value}"; } } \ No newline at end of file diff --git a/src/Controls/PropertyPresenter/TextBoxEx.cs b/src/Controls/PropertyPresenter/TextBoxEx.cs index 9570875..be9e113 100644 --- a/src/Controls/PropertyPresenter/TextBoxEx.cs +++ b/src/Controls/PropertyPresenter/TextBoxEx.cs @@ -2,164 +2,163 @@ using System.Windows.Controls; using System.Windows.Input; -namespace Controls +namespace Controls; + +/// +/// +/// Represents a TextBox that can update the binding on enter. +/// +public class TextBoxEx : TextBox { + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty MoveFocusOnEnterProperty = + DependencyProperty.Register( + nameof(MoveFocusOnEnter), typeof(bool), typeof(TextBoxEx), new UIPropertyMetadata(true)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty UpdateBindingOnEnterProperty = + DependencyProperty.Register( + nameof(UpdateBindingOnEnter), typeof(bool), typeof(TextBoxEx), new UIPropertyMetadata(true)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty ScrollToHomeOnFocusProperty = + DependencyProperty.Register(nameof(ScrollToHomeOnFocus), typeof(bool), typeof(TextBoxEx), new PropertyMetadata(true)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty SelectAllOnFocusProperty = + DependencyProperty.Register(nameof(SelectAllOnFocus), typeof(bool), typeof(TextBoxEx), new PropertyMetadata(true)); + /// /// - /// Represents a TextBox that can update the binding on enter. + /// Initializes a new instance of the class. /// - public class TextBoxEx : TextBox + public TextBoxEx() { - /// - /// Identifies the dependency property. - /// - public static readonly DependencyProperty MoveFocusOnEnterProperty = - DependencyProperty.Register( - "MoveFocusOnEnter", typeof(bool), typeof(TextBoxEx), new UIPropertyMetadata(true)); + GotKeyboardFocus += HandleGotKeyboardFocus; + } - /// - /// Identifies the dependency property. - /// - public static readonly DependencyProperty UpdateBindingOnEnterProperty = - DependencyProperty.Register( - "UpdateBindingOnEnter", typeof(bool), typeof(TextBoxEx), new UIPropertyMetadata(true)); + /// + /// Gets or sets a value indicating whether to select all on focus. + /// + /// + /// true if all should be selected; otherwise, false. + /// + public bool SelectAllOnFocus + { + get => (bool)GetValue(SelectAllOnFocusProperty); + set => SetValue(SelectAllOnFocusProperty, value); + } - /// - /// Identifies the dependency property. - /// - public static readonly DependencyProperty ScrollToHomeOnFocusProperty = - DependencyProperty.Register("ScrollToHomeOnFocus", typeof(bool), typeof(TextBoxEx), new PropertyMetadata(true)); + /// + /// Gets or sets a value indicating whether to scroll to home on focus. + /// + /// + /// true if scroll is enabled; otherwise, false. + /// + public bool ScrollToHomeOnFocus + { + get => (bool)GetValue(ScrollToHomeOnFocusProperty); + set => SetValue(ScrollToHomeOnFocusProperty, value); + } - /// - /// Identifies the dependency property. - /// - public static readonly DependencyProperty SelectAllOnFocusProperty = - DependencyProperty.Register("SelectAllOnFocus", typeof(bool), typeof(TextBoxEx), new PropertyMetadata(true)); + /// + /// Gets or sets a value indicating whether MoveFocusOnEnter. + /// + public bool MoveFocusOnEnter + { + get => (bool)GetValue(MoveFocusOnEnterProperty); - /// - /// - /// Initializes a new instance of the class. - /// - public TextBoxEx() + set => SetValue(MoveFocusOnEnterProperty, value); + } + + /// + /// Gets or sets a value indicating whether UpdateBindingOnEnter. + /// + public bool UpdateBindingOnEnter + { + get => (bool)GetValue(UpdateBindingOnEnterProperty); + + set => SetValue(UpdateBindingOnEnterProperty, value); + } + + /// + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + base.OnPreviewKeyDown(e); + switch (e.Key) { - GotKeyboardFocus += HandleGotKeyboardFocus; - } - - /// - /// Gets or sets a value indicating whether to select all on focus. - /// - /// - /// true if all should be selected; otherwise, false. - /// - public bool SelectAllOnFocus - { - get => (bool)GetValue(SelectAllOnFocusProperty); - set => SetValue(SelectAllOnFocusProperty, value); - } - - /// - /// Gets or sets a value indicating whether to scroll to home on focus. - /// - /// - /// true if scroll is enabled; otherwise, false. - /// - public bool ScrollToHomeOnFocus - { - get => (bool)GetValue(ScrollToHomeOnFocusProperty); - set => SetValue(ScrollToHomeOnFocusProperty, value); - } - - /// - /// Gets or sets a value indicating whether MoveFocusOnEnter. - /// - public bool MoveFocusOnEnter - { - get => (bool)GetValue(MoveFocusOnEnterProperty); - - set => SetValue(MoveFocusOnEnterProperty, value); - } - - /// - /// Gets or sets a value indicating whether UpdateBindingOnEnter. - /// - public bool UpdateBindingOnEnter - { - get => (bool)GetValue(UpdateBindingOnEnterProperty); - - set => SetValue(UpdateBindingOnEnterProperty, value); - } - - /// - protected override void OnPreviewKeyDown(KeyEventArgs e) - { - base.OnPreviewKeyDown(e); - switch (e.Key) - { - case Key.Enter: - if (!AcceptsReturn) + case Key.Enter: + if (!AcceptsReturn) + { + if (UpdateBindingOnEnter) { - if (UpdateBindingOnEnter) - { - // get the binding to the Text property - var bindingExpression = GetBindingExpression(TextProperty); - // update the source (do not update the target) - bindingExpression?.UpdateSource(); - } - - if (MoveFocusOnEnter) - { - // Move focus to next element - // http://madprops.org/blog/enter-to-tab-in-wpf/ - if (e.OriginalSource is UIElement uiElement) - { - var shift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift; - uiElement.MoveFocus(new TraversalRequest(shift ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next)); - } - } - - e.Handled = true; + // get the binding to the Text property + var bindingExpression = GetBindingExpression(TextProperty); + // update the source (do not update the target) + bindingExpression?.UpdateSource(); + } + + if (MoveFocusOnEnter) + { + // Move focus to next element + // http://madprops.org/blog/enter-to-tab-in-wpf/ + if (e.OriginalSource is UIElement uiElement) + { + var shift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift; + uiElement.MoveFocus(new TraversalRequest(shift ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next)); + } } - break; - case Key.Escape: - Undo(); - SelectAll(); e.Handled = true; - break; - } - } + } - /// - protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) - { - base.OnPreviewMouseLeftButtonDown(e); - - if (!IsKeyboardFocusWithin) - { + break; + case Key.Escape: + Undo(); SelectAll(); - Focus(); e.Handled = true; - } + break; } + } - /// - /// Handles the got keyboard focus event. - /// - /// The sender. - /// The instance containing the event data. - private void HandleGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) + /// + protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) + { + base.OnPreviewMouseLeftButtonDown(e); + + if (!IsKeyboardFocusWithin) { - if (SelectAllOnFocus) - { - SelectAll(); - } - - if (ScrollToHomeOnFocus) - { - ScrollToHome(); - } - + SelectAll(); + Focus(); e.Handled = true; } } + + /// + /// Handles the got keyboard focus event. + /// + /// The sender. + /// The instance containing the event data. + private void HandleGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) + { + if (SelectAllOnFocus) + { + SelectAll(); + } + + if (ScrollToHomeOnFocus) + { + ScrollToHome(); + } + + e.Handled = true; + } } \ No newline at end of file diff --git a/src/Controls/PropertyPresenter/TextComponent.cs b/src/Controls/PropertyPresenter/TextComponent.cs index 7a42ffd..6706288 100644 --- a/src/Controls/PropertyPresenter/TextComponent.cs +++ b/src/Controls/PropertyPresenter/TextComponent.cs @@ -1,31 +1,30 @@ using System.Windows; -namespace Controls +namespace Controls; + +/// +/// A component of the symbol +/// +public readonly struct TextComponent { /// - /// A component of the symbol + /// Constructor /// - public readonly struct TextComponent + /// + /// + public TextComponent(string text, BaselineAlignment style = BaselineAlignment.Baseline) { - /// - /// Constructor - /// - /// - /// - public TextComponent(string text, BaselineAlignment style = BaselineAlignment.Baseline) - { - Text = text; - Style = style; - } - - /// - /// Text of the symbol component - /// - public readonly string Text; - - /// - /// Style of the symbol component - /// - public readonly BaselineAlignment Style; + Text = text; + Style = style; } -} + + /// + /// Text of the symbol component + /// + public readonly string Text; + + /// + /// Style of the symbol component + /// + public readonly BaselineAlignment Style; +} \ No newline at end of file diff --git a/src/Controls/PropertyPresenter/ValueConverter.cs b/src/Controls/PropertyPresenter/ValueConverter.cs index 7da8804..ff0081a 100644 --- a/src/Controls/PropertyPresenter/ValueConverter.cs +++ b/src/Controls/PropertyPresenter/ValueConverter.cs @@ -11,90 +11,89 @@ using Brushes = System.Windows.Media.Brushes; using FontFamily = System.Windows.Media.FontFamily; using Point = System.Windows.Point; -namespace Controls +namespace Controls; + +/// +/// Makes an Bitmap from every Imageformat. +/// +public sealed class ObjectImageConverter : IValueConverter { - /// - /// Makes an Bitmap from every Imageformat. - /// - public sealed class ObjectImageConverter : IValueConverter + object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) { - object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) + const string dynResPrefix = "dynRes:"; + if (value is Bitmap bitmap) { - const string dynResPrefix = "dynRes:"; - if (value is Bitmap bitmap) - { - return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(16, 16)); - } - - if (value is not string strValue) return Binding.DoNothing; - if (strValue.StartsWith(dynResPrefix, StringComparison.Ordinal)) - { - var resource = Application.Current.TryFindResource(strValue.Replace(dynResPrefix, string.Empty , StringComparison.InvariantCulture)); - return resource is ImageSource source ? source : Binding.DoNothing; - } - - if (strValue.StartsWith("text:", StringComparison.Ordinal)) - { - var parts = strValue.Split(':'); - return parts.Length == 3 ? DrawText(WebUtility.HtmlDecode(parts[2]), parts[1], Brushes.Black) : Binding.DoNothing; - } - - return GetIcon(Geometry.Parse(strValue), null); + return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(16, 16)); } - object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => - Binding.DoNothing; - - /// - /// Get icon a ImageSource from geometry. - /// - /// geometry - /// color of the icon - /// - public static ImageSource GetIcon(Geometry geometry, Brush? brush) + if (value is not string strValue) return Binding.DoNothing; + if (strValue.StartsWith(dynResPrefix, StringComparison.Ordinal)) { - if (brush == null) - brush = Brushes.Black; - var drawing = new GeometryDrawing(brush, null, geometry); - return new DrawingImage(drawing); + var resource = Application.Current.TryFindResource(strValue.Replace(dynResPrefix, string.Empty , StringComparison.InvariantCulture)); + return resource is ImageSource source ? source : Binding.DoNothing; } - /// - /// Draw text as ImageSource from string. - /// - /// the text - /// font of the string - /// color of the string - /// - public static ImageSource DrawText(string text, string strFontFamily, Brush brush) + if (strValue.StartsWith("text:", StringComparison.Ordinal)) { - var fontFamily = new FontFamily(strFontFamily); - var formattedText = new FormattedText(text, - CultureInfo.GetCultureInfo("en-us"), - FlowDirection.LeftToRight, - new Typeface( - fontFamily, - FontStyles.Normal, - FontWeights.Normal, - FontStretches.Normal), - 64, brush, 1.5); - - var geometry = formattedText.BuildGeometry(new Point(0, 0)); - return GetIcon(geometry, null); + var parts = strValue.Split(':'); + return parts.Length == 3 ? DrawText(WebUtility.HtmlDecode(parts[2]), parts[1], Brushes.Black) : Binding.DoNothing; } + + return GetIcon(Geometry.Parse(strValue), null); + } + + object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => + Binding.DoNothing; + + /// + /// Get icon a ImageSource from geometry. + /// + /// geometry + /// color of the icon + /// + public static ImageSource GetIcon(Geometry geometry, Brush? brush) + { + if (brush == null) + brush = Brushes.Black; + var drawing = new GeometryDrawing(brush, null, geometry); + return new DrawingImage(drawing); } /// - /// Invert boolean converter + /// Draw text as ImageSource from string. /// - [ValueConversion(typeof(bool), typeof(bool))] - public class InverseBooleanConverter : IValueConverter + /// the text + /// font of the string + /// color of the string + /// + public static ImageSource DrawText(string text, string strFontFamily, Brush brush) { - /// - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => - value is bool b ? !b : throw new InvalidOperationException("The target must be a boolean"); + var fontFamily = new FontFamily(strFontFamily); + var formattedText = new FormattedText(text, + CultureInfo.GetCultureInfo("en-us"), + FlowDirection.LeftToRight, + new Typeface( + fontFamily, + FontStyles.Normal, + FontWeights.Normal, + FontStretches.Normal), + 64, brush, 1.5); - /// - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => Binding.DoNothing; + var geometry = formattedText.BuildGeometry(new Point(0, 0)); + return GetIcon(geometry, null); } +} + +/// +/// Invert boolean converter +/// +[ValueConversion(typeof(bool), typeof(bool))] +public class InverseBooleanConverter : IValueConverter +{ + /// + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => + value is bool b ? !b : throw new InvalidOperationException("The target must be a boolean"); + + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => Binding.DoNothing; } \ No newline at end of file