首先創建一個自定義控件,繼承自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 }