WPF。如何获取TextBlock的DrawingContext?

时间:2014-03-01 22:49:00

标签: c# wpf .net-4.5

我有一个TextBlock。我想在其内部绘制(在其当前视觉边界内)。我需要DrawingContext。

如何获得DrawingContext?

(MSDN说任何FrameworkElement都是Visual的后代,而Visual提供了对渲染的支持..但我不知道究竟是怎么回事)

请注意 - 此代码将每秒调用几次。我正在寻找最强大的高效解决方案(这就是我首先采用DrawingContext的原因)。

2 个答案:

答案 0 :(得分:2)

我做了什么:我编写了自己的装饰,装饰了文本块,使用OnRender来获取DrawingContext,我将文本直接写入装饰器并在每次更改时使Visual无效。

性能的提升(使用Ants剖析器仔细测量)比直接将文本写入文本块<强> 4.5倍,甚至比绑定字符串属性更强。

答案 1 :(得分:0)

为什么不在Canvas上叠加TextBlock并绘制到Canvas?

<强> XAML

 <Grid>
    <Canvas Background='Orange'
            x:Name='drawingCanvas'
            Width='{Binding ActualWidth, ElementName=textblock1, Mode=OneWay}'
            Height='{Binding ActualHeight, ElementName=textblock1, Mode=OneWay}' />

    <TextBlock Text='Example'
               x:Name='textblock1'
               HorizontalAlignment='Center'
               VerticalAlignment='Center'
               FontSize='40' />
  </Grid>

<强> CODE

public MainWindow() {
      InitializeComponent();
      this.Loaded += MainWindow_Loaded;
      _timer.Interval = TimeSpan.FromMilliseconds(100);
      _timer.Start();
      _timer.Tick += _timer_Tick;
    }

    private void _timer_Tick(object sender, EventArgs e) {
      var newX = _bezierSeg.Point1.X + .1;
      _bezierSeg.Point1 = new Point(Math.Sin(newX) * 12, 0);
    }

    private DispatcherTimer _timer = new DispatcherTimer();

    private BezierSegment _bezierSeg = new BezierSegment();

    private void MainWindow_Loaded(object sender, RoutedEventArgs e) {
      var arcPath = new Path();
      var figure = new PathFigure();

      figure.StartPoint = new Point(0, 0);
      var Point1 = new Point(textblock1.ActualHeight, 0);
      var Point2 = new Point(textblock1.ActualWidth - 30, textblock1.ActualHeight - 20);
      var Point3 = new Point(textblock1.ActualWidth, textblock1.ActualHeight);

      _bezierSeg.Point1 = Point1;
      _bezierSeg.Point2 = Point2;
      _bezierSeg.Point3 = Point3;

      var myPathSegmentCollection = new PathSegmentCollection();

      myPathSegmentCollection.Add(_bezierSeg);
      figure.Segments = myPathSegmentCollection;

      var pathCollection = new PathFigureCollection();
      pathCollection.Add(figure);

      var pathGeometry = new PathGeometry();
      pathGeometry.Figures = pathCollection;

      arcPath.Stroke = new SolidColorBrush(Colors.Red);
      arcPath.Fill = new SolidColorBrush(Colors.Yellow);
      arcPath.StrokeThickness = 2;

      arcPath.Data = pathGeometry;
      drawingCanvas.Children.Add(arcPath);
    }