原文:
WPF自定义空心文字
首先创建一个自定义控件,继承自FrameworkElement,“Generic.xaml”中可以不添加样式。
要自定义空心文字,要用到绘制格式化文本FormattedText类。FormattedText对象提供的文本格式设置功能比WPF提供的已有文本控件提供的相应功能更为强大。调用FormattedText构造函数,可以传入相应的参数,得到我们想要的文本样式。使用 MaxTextWidth 属性可以将文本约束为特定宽度。 文本将自动换行,以避免超过指定宽度。 使用 MaxTextHeight 属性可以将文本约束为特定高度。 超过指定高度的文本将显示一个省略号“…”。
接下来重写OnRender方法,在方法体中调用DrawingContext对象的DrawGeometry方法即可完成文本的绘制工作。
1 public class OutlinedText : FrameworkElement, IAddChild
2 {
3 /// <summary>
4 /// 静态构造函数
5 /// </summary>
6 static OutlinedText()
7 {
8 DefaultStyleKeyProperty.OverrideMetadata(typeof(OutlinedText), new FrameworkPropertyMetadata(typeof(OutlinedText)));
9 }
10
11
12 #region Private Fields
13
14 /// <summary>
15 /// 文字几何形状
16 /// </summary>
17 private Geometry m_TextGeometry;
18
19 #endregion
20
21
22 #region Private Methods
23
24 /// <summary>
25 /// 当依赖项属性改变文字无效时,创建新的空心文字对象来显示。
26 /// </summary>
27 /// <param name="d"></param>
28 /// <param name="e"></param>
29 private static void OnOutlineTextInvalidated(DependencyObject d, DependencyPropertyChangedEventArgs e)
30 {
31 if (Convert.ToString(e.NewValue) != Convert.ToString(e.OldValue))
32 {
33 ((OutlinedText)d).CreateText();
34 }
35 }
36
37 #endregion
38
39
40 #region FrameworkElement Overrides
41
42 /// <summary>
43 /// 重写绘制文字的方法。
44 /// </summary>
45 /// <param name="drawingContext">空心文字控件的绘制上下文。</param>
46 protected override void OnRender(DrawingContext drawingContext)
47 {
48 //CreateText();
49 // 基于设置的属性绘制空心文字控件。
50 drawingContext.DrawGeometry(Fill, new Pen(Stroke, StrokeThickness), m_TextGeometry);
51 }
52
53 /// <summary>
54 /// 基于格式化文字创建文字的几何轮廓。
55 /// </summary>
56 public void CreateText()
57 {
58 FontStyle fontStyle = FontStyles.Normal;
59 FontWeight fontWeight = FontWeights.Medium;
60 if (Bold == true)
61 fontWeight = FontWeights.Bold;
62 if (Italic == true)
63 fontStyle = FontStyles.Italic;
64 // 基于设置的属性集创建格式化的文字。
65 FormattedText formattedText = new FormattedText(
66 Text, CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight,
67 new Typeface(Font, fontStyle, fontWeight, FontStretches.Normal),
68 FontSize, Brushes.Black);
69 formattedText.MaxTextWidth = this.MaxTextWidth;
70 formattedText.MaxTextHeight = this.MaxTextHeight;
71 // 创建表示文字的几何对象。
72 m_TextGeometry = formattedText.BuildGeometry(new Point(0, 0));
73 // 基于格式化文字的大小设置空心文字的大小。
74 this.MinWidth = formattedText.Width;
75 this.MinHeight = formattedText.Height;
76 }
77
78 #endregion
79
80
81 #region DependencyProperties
82
83 /// <summary>
84 /// 指定将文本约束为特定宽度
85 /// </summary>
86 public double MaxTextWidth
87 {
88 get { return (double)GetValue(MaxTextWidthProperty); }
89 set { SetValue(MaxTextWidthProperty, value); }
90 }
91 /// <summary>
92 /// 指定将文本约束为特定宽度依赖属性
93 /// </summary>
94 public static readonly DependencyProperty MaxTextWidthProperty =
95 DependencyProperty.Register("MaxTextWidth", typeof(double), typeof(OutlinedText),
96 new FrameworkPropertyMetadata(1000.0, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlineTextInvalidated), null));
97
98 /// <summary>
99 /// 指定将文本约束为特定高度
100 /// </summary>
101 public double MaxTextHeight
102 {
103 get { return (double)GetValue(MaxTextHeightProperty); }
104 set { SetValue(MaxTextHeightProperty, value); }
105 }
106 /// <summary>
107 /// 指定将文本约束为特定高度依赖属性
108 /// </summary>
109 public static readonly DependencyProperty MaxTextHeightProperty =
110 DependencyProperty.Register("MaxTextHeight", typeof(double), typeof(OutlinedText),
111 new FrameworkPropertyMetadata(1000.0, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlineTextInvalidated), null));
112
113 /// <summary>
114 /// 指定字体是否加粗。
115 /// </summary>
116 public bool Bold
117 {
118 get { return (bool)GetValue(BoldProperty); }
119 set { SetValue(BoldProperty, value); }
120 }
121 /// <summary>
122 /// 指定字体是否加粗依赖属性。
123 /// </summary>
124 public static readonly DependencyProperty BoldProperty = DependencyProperty.Register(
125 "Bold", typeof(bool), typeof(OutlinedText),
126 new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlineTextInvalidated), null));
127
128 /// <summary>
129 /// 指定填充字体的画刷颜色。
130 /// </summary>
131 ///
132 public Brush Fill
133 {
134 get { return (Brush)GetValue(FillProperty); }
135 set { SetValue(FillProperty, value); }
136 }
137 /// <summary>
138 /// 指定填充字体的画刷颜色依赖属性。
139 /// </summary>
140 public static readonly DependencyProperty FillProperty = DependencyProperty.Register(
141 "Fill", typeof(Brush), typeof(OutlinedText),
142 new FrameworkPropertyMetadata(new SolidColorBrush(Colors.LightSteelBlue), FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlineTextInvalidated), null));
143
144 /// <summary>
145 /// 指定文字显示的字体。
146 /// </summary>
147 public FontFamily Font
148 {
149 get { return (FontFamily)GetValue(FontProperty); }
150 set { SetValue(FontProperty, value); }
151 }
152 /// <summary>
153 /// 指定文字显示的字体依赖属性。
154 /// </summary>
155 public static readonly DependencyProperty FontProperty = DependencyProperty.Register(
156 "Font", typeof(FontFamily), typeof(OutlinedText),
157 new FrameworkPropertyMetadata(new FontFamily("Arial"), FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlineTextInvalidated), null));
158
159 /// <summary>
160 /// 指定字体大小。
161 /// </summary>
162 public double FontSize
163 {
164 get { return (double)GetValue(FontSizeProperty); }
165 set { SetValue(FontSizeProperty, value); }
166 }
167 /// <summary>
168 /// 指定字体大小依赖属性。
169 /// </summary>
170 public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register(
171 "FontSize", typeof(double), typeof(OutlinedText),
172 new FrameworkPropertyMetadata((double)48.0, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlineTextInvalidated), null));
173
174 /// <summary>
175 /// 指定字体是否显示斜体字体样式。
176 /// </summary>
177 public bool Italic
178 {
179 get { return (bool)GetValue(ItalicProperty); }
180 set { SetValue(ItalicProperty, value); }
181 }
182 /// <summary>
183 /// 指定字体是否显示斜体字体样式依赖属性。
184 /// </summary>
185 public static readonly DependencyProperty ItalicProperty = DependencyProperty.Register(
186 "Italic", typeof(bool), typeof(OutlinedText),
187 new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlineTextInvalidated), null));
188
189 /// <summary>
190 /// 指定绘制空心字体边框画刷的颜色。
191 /// </summary>
192 public Brush Stroke
193 {
194 get { return (Brush)GetValue(StrokeProperty); }
195 set { SetValue(StrokeProperty, value); }
196 }
197 /// <summary>
198 /// 指定绘制空心字体边框画刷的颜色依赖属性。
199 /// </summary>
200 public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register(
201 "Stroke", typeof(Brush), typeof(OutlinedText),
202 new FrameworkPropertyMetadata(new SolidColorBrush(Colors.Teal), FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlineTextInvalidated), null));
203
204 /// <summary>
205 /// 指定空心字体边框大小。
206 /// </summary>
207 public ushort StrokeThickness
208 {
209 get { return (ushort)GetValue(StrokeThicknessProperty); }
210 set { SetValue(StrokeThicknessProperty, value); }
211 }
212 /// <summary>
213 /// 指定空心字体边框大小依赖属性。
214 /// </summary>
215 public static readonly DependencyProperty StrokeThicknessProperty =
216 DependencyProperty.Register("StrokeThickness",
217 typeof(ushort), typeof(OutlinedText),
218 new FrameworkPropertyMetadata((ushort)0, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlineTextInvalidated), null));
219
220 /// <summary>
221 /// 指定要显示的文字字符串。
222 /// </summary>
223 public string Text
224 {
225 get { return (string)GetValue(TextProperty); }
226 set { SetValue(TextProperty, value); }
227 }
228 /// <summary>
229 /// 指定要显示的文字字符串依赖属性。
230 /// </summary>
231 public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
232 "Text", typeof(string), typeof(OutlinedText),
233 new FrameworkPropertyMetadata("",
234 FrameworkPropertyMetadataOptions.AffectsRender,
235 new PropertyChangedCallback(OnOutlineTextInvalidated),
236 null));
237
238 #endregion
239
240
241 #region Public Methods
242
243 /// <summary>
244 /// 添加子对象。
245 /// </summary>
246 /// <param name="value">要添加的子对象。</param>
247 public void AddChild(Object value)
248 { }
249
250 /// <summary>
251 /// 将节点的文字内容添加到对象。
252 /// </summary>
253 /// <param name="value">要添加到对象的文字。</param>
254 public void AddText(string value)
255 {
256 Text = value;
257 }
258
259 #endregion
260 }
来源:oschina
链接:https://my.oschina.net/u/4363105/blog/4262662