|
FormattedText为WPF应用程序中的绘图文本提供低级别的控制。
FormattedText ft = new FormattedText(Text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, Typeface, FontSize, Foreground);
Geometry geometry = ft.BuildGeometry(new Point(0.0, 0.0));
dc.DrawText(ft, new Point(0.0, 0.0));
dc.DrawGeometry(null, new Pen(BorderBrush, Stroke), geometry);
FormattedText元素的可视化示例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading; //dispatcher
using System.Globalization;//cultureinfo
namespace wpf_Font
{
public class OutlineTextElement : FrameworkElement
{
public FontFamily FontFamily { get; set; }
public FontWeight FontWeight { get; set; }
public FontStyle FontStyle { get; set; }
public int FontSize { get; set; }
public int Stroke { get; set; }
public SolidColorBrush Background { get; set; }
public SolidColorBrush Foreground { get; set; }
public SolidColorBrush BorderBrush { get; set; }
private Typeface Typeface;
private VisualCollection Visuals;
private Action Render_Text_Action;
private DispatcherOperation CurrentDispatcherOperation;
private string text;
public string Text
{
get { return text; }
set
{
if (String.Equals(text, value, StringComparison.CurrentCulture))return;
text = value;
Render_Text();
}
}
public OutlineTextElement()
{
//---------< Init: OutlineTextElement() >---------
Focusable = true;
Visuals = new VisualCollection(this);
FontFamily = new FontFamily(&#34;Century&#34;);
FontWeight = FontWeights.Bold;
FontStyle = FontStyles.Normal;
FontSize = 42;
Stroke = 3;
Typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretches.Normal);
Foreground = Brushes.Black;
BorderBrush = Brushes.Gold;
//< draw >
Render_Text_Action = () => { Render_FormattedText(); }; //define RenderTextAction
Loaded += (o, e) => { Render_Text(); }; //call previous rendertextAction
//</ draw >
//< events >
MouseDown += OutlineTextElement_MouseDown;
KeyDown += OutlineTextElement_KeyDown;
//</ events >
//---------</ Init: OutlineTextElement() >---------
}
private void OutlineTextElement_MouseDown(object sender, MouseButtonEventArgs e)
{
//MessageBox.Show(&#34;Mousedown&#34;);
Focus();
}
private void OutlineTextElement_KeyDown(object sender, KeyEventArgs e)
{
//MessageBox.Show(&#34;Key=&#34; + e.Key);
//OutlineTextElement ctl = sender as OutlineTextElement;
//string text = ctl.text;
text = text + e.Key;
Render_Text();
}
private void Render_FormattedText()
{
//---------< Render_FormattedText() >---------
Visuals.Clear();
DrawingVisual visual = new DrawingVisual();
using (DrawingContext dc = visual.RenderOpen())
{
FormattedText ft = new FormattedText(Text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, Typeface, FontSize, Foreground);
Geometry geometry = ft.BuildGeometry(new Point(0.0, 0.0));
dc.DrawText(ft, new Point(0.0, 0.0));
dc.DrawGeometry(null, new Pen(BorderBrush, Stroke), geometry);
//// Create a set of polygons by flattening the Geometry object.
//PathGeometry pathGeometry = geometry.GetFlattenedPathGeometry();
//// Supply the empty Path element in XAML with the PathGeometry in order to render the polygons.
//path.Data = pathGeometry;
//// Use the PathGeometry for the matrix animation,
//// allowing the ellipse to follow the path of the polygons.
//matrixAnimation.PathGeometry = pathGeometry;
}
Visuals.Add(visual);
//---------</ Render_FormattedText() >---------
}
private void Render_Text()
{
//---------< Rendering() >---------
if (CurrentDispatcherOperation != null)
CurrentDispatcherOperation.Abort();
CurrentDispatcherOperation = Dispatcher.BeginInvoke(Render_Text_Action, DispatcherPriority.Render, null);
CurrentDispatcherOperation.Aborted += (o, e) => { CurrentDispatcherOperation = null; };
CurrentDispatcherOperation.Completed += (o, e) => { CurrentDispatcherOperation = null; };
//---------</ Rendering() >---------
}
protected override Visual GetVisualChild(int index)
{
return Visuals[index];
}
protected override int VisualChildrenCount
{
get { return Visuals.Count; }
}
}
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
#region Buttons
//----------------------< Buttons >----------------------
private void btnShow_Click(object sender, RoutedEventArgs e)
{
fl_Update_Text();
}
//----------------------</ Buttons >----------------------
#endregion
private void tbxText_TextChanged(object sender, TextChangedEventArgs e)
{
fl_Update_Text();
}
#region Functions
//----------------------< Functions >----------------------
private void fl_Update_Text()
{
if (ctlFormattedText != null)
{
ctlFormattedText.Text = tbxText.Text;
ctlFormattedText.UpdateLayout();
}
}
private void ctlFormattedText_KeyDown(object sender, KeyEventArgs e)
{
}
//----------------------</ Functions >----------------------
#endregion
}
}
XAML
<Window x:Class=&#34;wpf_Font.MainWindow&#34;
xmlns=&#34;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#34;
xmlns:x=&#34;http://schemas.microsoft.com/winfx/2006/xaml&#34;
xmlns:d=&#34;http://schemas.microsoft.com/expression/blend/2008&#34;
xmlns:mc=&#34;http://schemas.openxmlformats.org/markup-compatibility/2006&#34;
xmlns:local=&#34;clr-namespace:wpf_Font&#34;
mc:Ignorable=&#34;d&#34;
Title=&#34;MainWindow&#34; Height=&#34;350&#34; Width=&#34;525&#34;>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height=&#34;46&#34;/>
<RowDefinition Height=&#34;275*&#34;/>
</Grid.RowDefinitions>
<TextBox x:Name=&#34;tbxText&#34; HorizontalAlignment=&#34;Left&#34; Margin=&#34;18,9,0,13.4&#34; TextWrapping=&#34;Wrap&#34; Text=&#34;Hello&#34; Width=&#34;120&#34; TextChanged=&#34;tbxText_TextChanged&#34; />
<Button x:Name=&#34;btnShow&#34; Content=&#34;Show Text&#34; Margin=&#34;149,9,0,16.4&#34; d:LayoutOverrides=&#34;Height&#34; HorizontalAlignment=&#34;Left&#34; Width=&#34;75&#34; Click=&#34;btnShow_Click&#34;/>
<local:OutlineTextElement x:Name=&#34;ctlFormattedText&#34; Text=&#34;Hello&#34; Grid.Row=&#34;1&#34; >
</local:OutlineTextElement>
</Grid>
</Window> |
|