日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

水印控件

發布時間:2025/3/20 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 水印控件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

用裝飾器實現,裝飾器最大的好處就是不影響控件原本的表現的基礎之上增加一些顯示的效果,而且利于擴展。

通過擴展控件也能實現,但是部分控件是密封的,比如PasswordBox,而且還需要修改樣式是比較麻煩費力;

效果

?

?

WatermarkAdorner:定義了附加屬性、在Text的附加屬性的OnTextChanged中給對應的控件的加載事件添加了Adorner(利用反射消除控件類型及對應的控件裝飾器的判斷)

/// <summary>/// 水印裝飾器 /// </summary>public class WatermarkAdorner : Adorner{public WatermarkAdorner(UIElement adornedElement): base(adornedElement){IsHitTestVisible = false; //不可命中 InvalidateVisual();}//強制布局發生改變,根據當前信息實時繪制protected void Adorner_RoutedEvent(object sender, RoutedEventArgs e){InvalidateVisual();}#region 附加屬性public static Thickness GetMargin(DependencyObject obj){return (Thickness)obj.GetValue(MarginProperty);}public static void SetMargin(DependencyObject obj, Thickness value){obj.SetValue(MarginProperty, value);}public new readonly static DependencyProperty MarginProperty =DependencyProperty.RegisterAttached("Margin", typeof(Thickness), typeof(WatermarkAdorner), new PropertyMetadata(new Thickness(0)));public static string GetText(DependencyObject obj){return (string)obj.GetValue(TextProperty);}public static void SetText(DependencyObject obj, string value){obj.SetValue(TextProperty, value);}/// <summary>/// 文本屬性/// </summary>public static readonly DependencyProperty TextProperty =DependencyProperty.RegisterAttached("Text", typeof(string), typeof(WatermarkAdorner), new PropertyMetadata(string.Empty, OnTextChanged));private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){var element = d as FrameworkElement;if (element != null){WatermarkAdorner adorner = new WatermarkAdorner(element);WatermarkAdorner watermarkAdorner = null;Type type = adorner.GetType();Assembly assembly = type.Assembly;watermarkAdorner = (WatermarkAdorner)assembly.CreateInstance(type.Namespace + "." + element.GetType().Name + "WatermarkAdorner", false, BindingFlags.CreateInstance, null, new object[] { element }, CultureInfo.CurrentCulture, null);element.Loaded += (sender, arg) =>{if (watermarkAdorner != null){AdornerLayer.GetAdornerLayer(element).Add(watermarkAdorner);}};}}public static Brush GetForeground(DependencyObject obj){return (Brush)obj.GetValue(ForegroundProperty);}public static void SetForeground(DependencyObject obj, Brush value){obj.SetValue(ForegroundProperty, value);}/// <summary>/// 前景色/// </summary>public static readonly DependencyProperty ForegroundProperty =DependencyProperty.RegisterAttached("Foreground", typeof(Brush), typeof(WatermarkAdorner), new UIPropertyMetadata(Brushes.Gray));public static Brush GetBackground(DependencyObject obj){return (Brush)obj.GetValue(BackgroundProperty);}public static void SetBackground(DependencyObject obj, Brush value){obj.SetValue(BackgroundProperty, value);}/// <summary>/// 背景色/// </summary>public static readonly DependencyProperty BackgroundProperty =DependencyProperty.RegisterAttached("Background", typeof(Brush), typeof(WatermarkAdorner), new UIPropertyMetadata(Brushes.Transparent));public static FontStyle GetFontStyle(DependencyObject obj){return (FontStyle)obj.GetValue(FontStyleProperty);}public static void SetFontStyle(DependencyObject obj, FontStyle value){obj.SetValue(FontStyleProperty, value);}/// <summary>/// 字體風格/// </summary>public static readonly DependencyProperty FontStyleProperty =DependencyProperty.RegisterAttached("FontStyle", typeof(FontStyle), typeof(WatermarkAdorner), new UIPropertyMetadata(FontStyles.Italic));#endregion} }

?


TextBoxWatermarkAdorner:構造函數為控件的對應事件訂閱刷新水印事件、OnRender方法判斷是否滿足添加水印的條件以及繪制水印

public class TextBoxWatermarkAdorner : WatermarkAdorner{//被裝飾的文本輸入框private readonly TextBox _adornerTextBox;public TextBoxWatermarkAdorner(UIElement adornedElement): base(adornedElement){var adornerTextBox = adornedElement as TextBox;if (adornerTextBox != null){_adornerTextBox = adornerTextBox;_adornerTextBox.LostFocus += Adorner_RoutedEvent;_adornerTextBox.GotFocus += Adorner_RoutedEvent;_adornerTextBox.TextChanged += Adorner_RoutedEvent;}InvalidateVisual();}protected override void OnRender(DrawingContext drawingContext){if (_adornerTextBox != null && (!_adornerTextBox.IsFocused && string.IsNullOrEmpty(_adornerTextBox.Text))){FormattedText formattedText =new FormattedText(GetText(_adornerTextBox),CultureInfo.CurrentUICulture,_adornerTextBox.FlowDirection,_adornerTextBox.FontFamily.GetTypefaces().FirstOrDefault(),_adornerTextBox.FontSize,GetForeground(_adornerTextBox));formattedText.SetFontStyle(GetFontStyle(_adornerTextBox));drawingContext.DrawText(formattedText,new Point(GetMargin(_adornerTextBox).Left, GetMargin(_adornerTextBox).Left));}}}

?

?

PasswordBoxWatermarkAdorner:構造函數為控件的對應事件訂閱刷新水印事件、OnRender方法判斷是否滿足添加水印的條件以及繪制水印

?

public class PasswordBoxWatermarkAdorner : WatermarkAdorner{private readonly PasswordBox _adornedPasswordBox;public PasswordBoxWatermarkAdorner(UIElement adornedElement): base(adornedElement){var passwordBox = adornedElement as PasswordBox;if (passwordBox != null){_adornedPasswordBox = passwordBox;_adornedPasswordBox.LostFocus += Adorner_RoutedEvent;_adornedPasswordBox.GotFocus += Adorner_RoutedEvent;_adornedPasswordBox.PasswordChanged += Adorner_RoutedEvent;}InvalidateVisual();}protected override void OnRender(DrawingContext drawingContext){if (_adornedPasswordBox != null && (_adornedPasswordBox.IsFocused || !string.IsNullOrEmpty(_adornedPasswordBox.Password)))return;FormattedText formatted = new FormattedText(GetText(_adornedPasswordBox), CultureInfo.CurrentCulture,GetFlowDirection(_adornedPasswordBox), _adornedPasswordBox.FontFamily.GetTypefaces().FirstOrDefault(),_adornedPasswordBox.FontSize, GetForeground(_adornedPasswordBox));formatted.SetFontStyle(GetFontStyle(_adornedPasswordBox));drawingContext.DrawText(formatted,new Point(GetMargin(_adornedPasswordBox).Left, GetMargin(_adornedPasswordBox).Top));}}

?


界面使用

<Window x:Class="Watermarker.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:Watermarker"Title="MainWindow" Height="350" Width="525"><StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"><TextBox Height="40" Width="100"FontSize="18"local:TextBoxWatermarkAdorner.Text="請輸入文本"local:TextBoxWatermarkAdorner.Margin="5,5,0,0"/><PasswordBox Height="40" Width="100"local:PasswordBoxWatermarkAdorner.Text="請輸入密碼"local:PasswordBoxWatermarkAdorner.Margin="5,5,0,0"/></StackPanel> </Window>

?

2016/07/05

發現一處Bug:

AdornerLayer.GetAdornerLayer(element)可能存在返回值為空的狀況,那么程序會直接崩潰,不夠友好,這里是比較粗心大意的一個寫代碼陋習,在使用引用對象的時候沒有檢查值是否存在。
1 public class WatermarkAdorner : Adorner 2 { 3 public WatermarkAdorner(UIElement adornedElement) 4 : base(adornedElement) 5 { 6 IsHitTestVisible = false; //不可命中 7 InvalidateVisual(); 8 } 9 10 //強制布局發生改變,根據當前信息實時繪制 11 protected void Adorner_RoutedEvent(object sender, RoutedEventArgs e) 12 { 13 InvalidateVisual(); 14 } 15 16 #region 附加屬性 17 18 public static Thickness GetMargin(DependencyObject obj) 19 { 20 return (Thickness)obj.GetValue(MarginProperty); 21 } 22 23 public static void SetMargin(DependencyObject obj, Thickness value) 24 { 25 obj.SetValue(MarginProperty, value); 26 } 27 28 public new readonly static DependencyProperty MarginProperty = 29 DependencyProperty.RegisterAttached("Margin", typeof(Thickness), typeof(WatermarkAdorner), new PropertyMetadata(new Thickness(0))); 30 31 public static string GetText(DependencyObject obj) 32 { 33 return (string)obj.GetValue(TextProperty); 34 } 35 36 public static void SetText(DependencyObject obj, string value) 37 { 38 obj.SetValue(TextProperty, value); 39 } 40 41 /// <summary> 42 /// 文本屬性 43 /// </summary> 44 public static readonly DependencyProperty TextProperty = 45 DependencyProperty.RegisterAttached("Text", typeof(string), typeof(WatermarkAdorner), new PropertyMetadata(string.Empty, OnTextChanged)); 46 47 private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 48 { 49 var element = d as FrameworkElement; 50 if (element != null) 51 { 52 WatermarkAdorner adorner = new WatermarkAdorner(element); 53 WatermarkAdorner watermarkAdorner = null; 54 Type type = adorner.GetType(); 55 Assembly assembly = type.Assembly; 56 watermarkAdorner = (WatermarkAdorner)assembly.CreateInstance(type.Namespace + "." + element.GetType().Name + "WatermarkAdorner", false, BindingFlags.CreateInstance, null, new object[] { element }, CultureInfo.CurrentCulture, null); 57 58 element.Loaded += (sender, arg) => 59 { 60 if (watermarkAdorner != null) 61 { 62 var adornerLayer = GetAdornerLayer(element); 63 if (adornerLayer != null) 64 { 65 adornerLayer.Add(watermarkAdorner); 66 } 67 } 68 }; 69 } 70 } 71 72 private static AdornerLayer GetAdornerLayer(FrameworkElement element) 73 { 74 if (element == null) return null; 75 76 AdornerLayer layer = AdornerLayer.GetAdornerLayer(element); 77 var parent = element.Parent as FrameworkElement; 78 while (layer == null) 79 { 80 if (parent != null) 81 { 82 layer = AdornerLayer.GetAdornerLayer(parent); 83 parent = parent.Parent as FrameworkElement; 84 } 85 else break; 86 } 87 88 return layer; 89 } 90 91 public static Brush GetForeground(DependencyObject obj) 92 { 93 return (Brush)obj.GetValue(ForegroundProperty); 94 } 95 96 public static void SetForeground(DependencyObject obj, Brush value) 97 { 98 obj.SetValue(ForegroundProperty, value); 99 } 100 101 /// <summary> 102 /// 前景色 103 /// </summary> 104 public static readonly DependencyProperty ForegroundProperty = 105 DependencyProperty.RegisterAttached("Foreground", typeof(Brush), typeof(WatermarkAdorner), new UIPropertyMetadata(Brushes.Gray)); 106 107 public static Brush GetBackground(DependencyObject obj) 108 { 109 return (Brush)obj.GetValue(BackgroundProperty); 110 } 111 112 public static void SetBackground(DependencyObject obj, Brush value) 113 { 114 obj.SetValue(BackgroundProperty, value); 115 } 116 117 /// <summary> 118 /// 背景色 119 /// </summary> 120 public static readonly DependencyProperty BackgroundProperty = 121 DependencyProperty.RegisterAttached("Background", typeof(Brush), typeof(WatermarkAdorner), new UIPropertyMetadata(Brushes.Transparent)); 122 123 124 public static FontStyle GetFontStyle(DependencyObject obj) 125 { 126 return (FontStyle)obj.GetValue(FontStyleProperty); 127 } 128 129 public static void SetFontStyle(DependencyObject obj, FontStyle value) 130 { 131 obj.SetValue(FontStyleProperty, value); 132 } 133 134 /// <summary> 135 /// 字體風格 136 /// </summary> 137 public static readonly DependencyProperty FontStyleProperty = 138 DependencyProperty.RegisterAttached("FontStyle", typeof(FontStyle), typeof(WatermarkAdorner), new UIPropertyMetadata(FontStyles.Italic)); 139 140 #endregion 141 }

2016.8.16添加,用于WatermarkAdorner在無法獲取AdornerLayer的場景下獲取AdornerLayer

?

轉載于:https://www.cnblogs.com/XzcBlog/p/4940303.html

總結

以上是生活随笔為你收集整理的水印控件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。