namespace AntDesignWPF.Helpers { using System; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Media; public static class Input { #region Attached Properties public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.RegisterAttached("Placeholder", typeof(string), typeof(Input), new PropertyMetadata(string.Empty)); /// /// Gets the placeholder for the input control. /// [AttachedPropertyBrowsableForType(typeof(TextBoxBase))] [AttachedPropertyBrowsableForType(typeof(PasswordBox))] [AttachedPropertyBrowsableForType(typeof(ComboBox))] public static string GetPlaceholder(DependencyObject obj) { return (string)obj.GetValue(PlaceholderProperty); } /// /// Sets the placeholder for the input control. /// public static void SetPlaceholder(DependencyObject obj, string value) { obj.SetValue(PlaceholderProperty, value); } public static readonly DependencyProperty PlaceholderBrushProperty = DependencyProperty.RegisterAttached("PlaceholderBrush", typeof(Brush), typeof(Input), new FrameworkPropertyMetadata( Brushes.Silver, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender | FrameworkPropertyMetadataOptions.Inherits)); /// /// Gets the placeholder foreground brush for the input control. /// [AttachedPropertyBrowsableForType(typeof(TextBoxBase))] [AttachedPropertyBrowsableForType(typeof(PasswordBox))] [AttachedPropertyBrowsableForType(typeof(ComboBox))] public static Brush GetPlaceholderBrush(DependencyObject obj) { return (Brush)obj.GetValue(PlaceholderBrushProperty); } /// /// Sets the placeholder foreground brush for the input control. /// public static void SetPlaceholderBrush(DependencyObject obj, Brush value) { obj.SetValue(PlaceholderBrushProperty, value); } public static readonly DependencyProperty PrefixProperty = DependencyProperty.RegisterAttached("Prefix", typeof(object), typeof(Input), new PropertyMetadata(null)); /// /// Gets the prefix object of the input control. /// [AttachedPropertyBrowsableForType(typeof(TextBox))] [AttachedPropertyBrowsableForType(typeof(PasswordBox))] [AttachedPropertyBrowsableForType(typeof(ComboBox))] public static object GetPrefix(DependencyObject obj) { return obj.GetValue(PrefixProperty); } /// /// Sets the prefix object of the input control. /// public static void SetPrefix(DependencyObject obj, object value) { obj.SetValue(PrefixProperty, value); } public static readonly DependencyProperty SuffixProperty = DependencyProperty.RegisterAttached("Suffix", typeof(object), typeof(Input), new PropertyMetadata(null)); /// /// Gets the suffix object of the input control. /// [AttachedPropertyBrowsableForType(typeof(TextBox))] [AttachedPropertyBrowsableForType(typeof(PasswordBox))] public static object GetSuffix(DependencyObject obj) { return obj.GetValue(SuffixProperty); } /// /// Sets the suffix object of the input control. /// public static void SetSuffix(DependencyObject obj, object value) { obj.SetValue(SuffixProperty, value); } public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached("Password", typeof(string), typeof(Input), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnPasswordChanged))); private static void OnPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is PasswordBox passwordBox) { var newVal = (string)e.NewValue; // Sync password if (newVal != passwordBox.Password) { passwordBox.Password = newVal; } } } /// /// Gets the password currently held by the PasswordBox. /// [AttachedPropertyBrowsableForType(typeof(PasswordBox))] public static string GetPassword(DependencyObject obj) { return (string)obj.GetValue(PasswordProperty); } /// /// Sets the password currently held by the PasswordBox. /// public static void SetPassword(DependencyObject obj, string value) { obj.SetValue(PasswordProperty, value); } public static readonly DependencyProperty ClearableProperty = DependencyProperty.RegisterAttached("Clearable", typeof(bool), typeof(Input), new PropertyMetadata(false)); /// /// Gets whether the input control has a clear behavior. /// [AttachedPropertyBrowsableForType(typeof(TextBox))] [AttachedPropertyBrowsableForType(typeof(PasswordBox))] [AttachedPropertyBrowsableForType(typeof(ComboBox))] public static bool GetClearable(DependencyObject obj) { return (bool)obj.GetValue(ClearableProperty); } /// /// Sets whether the input control has a clear behavior. /// public static void SetClearable(DependencyObject obj, bool value) { obj.SetValue(ClearableProperty, value); } public static readonly DependencyProperty EyeableProperty = DependencyProperty.RegisterAttached("Eyeable", typeof(bool), typeof(Input), new PropertyMetadata(false)); /// /// Gets whether the password currently held by PasswordBox is displayed in text. /// [AttachedPropertyBrowsableForType(typeof(PasswordBox))] public static bool GetEyeable(DependencyObject obj) { return (bool)obj.GetValue(EyeableProperty); } /// /// Sets whether the password currently held by PasswordBox is displayed in text. /// public static void SetEyeable(DependencyObject obj, bool value) { obj.SetValue(EyeableProperty, value); } public static readonly DependencyProperty ClearEnabledProperty = DependencyProperty.RegisterAttached("ClearEnabled", typeof(bool), typeof(Input), new PropertyMetadata(false, OnClearEnabled)); /// /// Gets the clear enable state of the control. /// public static bool GetClearEnabled(DependencyObject obj) { return (bool)obj.GetValue(ClearEnabledProperty); } /// /// Sets the clear enable state of the control. /// public static void SetClearEnabled(DependencyObject obj, bool value) { obj.SetValue(ClearEnabledProperty, value); } private static void OnClearEnabled(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is UIElement) { if ((bool)e.NewValue) { ((UIElement)d).MouseLeftButtonUp += OnClear; } else { ((UIElement)d).MouseLeftButtonUp -= OnClear; } } } #endregion #region Private Methods private static void OnClear(object sender, RoutedEventArgs e) { if (sender is DependencyObject d) { var parent = d.GetAncestors().FirstOrDefault(a => a is TextBox || a is PasswordBox || a is ComboBox); if (GetClearable(parent)) { if (parent is TextBox) { ((TextBox)parent).Clear(); ((TextBox)parent).GetBindingExpression(TextBox.TextProperty)?.UpdateSource(); } else if (parent is PasswordBox) { ((PasswordBox)parent).Clear(); ((PasswordBox)parent).GetBindingExpression(PasswordProperty)?.UpdateSource(); } else if (parent is ComboBox) { if (((ComboBox)parent).IsEditable) { ((ComboBox)parent).Text = string.Empty; ((ComboBox)parent).GetBindingExpression(ComboBox.TextProperty)?.UpdateSource(); } ((ComboBox)parent).SelectedItem = null; ((ComboBox)parent).GetBindingExpression(Selector.SelectedItemProperty)?.UpdateSource(); } } } } #endregion } }