【问题标题】:WPF. How to get a DrawingContext for a TextBlock?WPF。如何获取 TextBlock 的 DrawingContext?
【发布时间】:2014-03-03 20:08:12
【问题描述】:

我有一个文本块。我想在它里面画画(在它的 current 视觉边界内)。我需要 DrawingContext 。

如何获得 DrawingContext?

(MSDN 说任何 FrameworkElement 都是 Visual 的后代,并且 Visual 提供了对渲染的支持。但我无法找到确切的方法)

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

【问题讨论】:

    标签: c# wpf .net-4.5


    【解决方案1】:

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

    与将文本直接写入文本块甚至比绑定字符串属性相比,性能提升(使用 Ants 分析器仔细测量)4.5 倍

    【讨论】:

      【解决方案2】:

      为什么不将 TextBlock 覆盖在 Canvas 上并绘制到 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>
      

      代码

      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);
          }
      

      【讨论】:

      • 只需在画布上添加元素。你需要绘图上下文做什么,你可以添加和动画元素?
      • 你没有回答我的问题
      • 好吧,如果您有需要绘图上下文的完美理由,请忽略我的回答。
      • BoppityBop - @WaltRitcher 给了你一个正确的答案。我想您正在寻找这样的东西:msdn.microsoft.com/en-us/library/ms748838(v=vs.110).aspx 但沃尔特·里彻的答案是正确的。不要滥用 WPF。 TextBlock 不是为在其上绘图而创建的
      猜你喜欢
      • 2010-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-18
      • 1970-01-01
      相关资源
      最近更新 更多