代码之家  ›  专栏  ›  技术社区  ›  repka

DrawingVisual未刷新

  •  7
  • repka  · 技术社区  · 15 年前

    我创造我自己 FrameworkElement 超驰 VisualChildrenCount{get;} GetVisualChild(int index) 通过归还我自己的 DrawingVisual 实例。

    如果在初始呈现后修改视觉内容(例如在计时器处理程序中),请使用 DrawingVisual.RenderOpen() 在上下文中,元素不会被刷新。

    下面是最简单的示例:

    using System;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Threading;
    
    namespace VisualTest
    {
        public class TestControl : FrameworkElement
        {
            private readonly DrawingVisual _visual = new DrawingVisual();
    
            public TestControl()
            {
                Draw(false);
    
                var timer = new DispatcherTimer {Interval = new TimeSpan(0, 0, 2)};
                timer.Tick += (sender, args) =>
                                  {
                                      Draw(true);
                                      InvalidateVisual();
                                      timer.Stop();
                                  };
                timer.Start();
            }
    
            protected override Visual GetVisualChild(int index)
            {
                return _visual;
            }
    
            protected override int VisualChildrenCount
            {
                get { return 1; }
            }
    
            private void Draw(bool second)
            {
                DrawingContext ctx = _visual.RenderOpen();
                if (!second)
                    ctx.DrawRoundedRectangle(Brushes.Green, null, new Rect(0, 0, 200, 200), 20, 20);
                else
                    ctx.DrawEllipse(Brushes.Red, null, new Point(100, 100), 100, 100);
                ctx.Close();
            }
        }
    }
    

    InvalidateVisual() 什么也不做。但是,如果您调整包含元素的窗口的大小,它将得到更新。

    关于如何正确刷新内容有什么想法吗?更可取地 没有 为我的元素引入新的依赖属性。

    3 回复  |  直到 8 年前
        1
  •  9
  •   SMART_n    15 年前

    添加

    this.AddVisualChild(_visual);
    this.AddLogicalChild(_visual);
    

    到TestControl类构造函数。

        2
  •  6
  •   Community CDub    8 年前

    基于 SMART_n's answer ,这里有一个不泄漏内存的改进解决方案:

        public TestControl()
        {
            Loaded += AddVisualToTree;
            Unloaded += RemoveVisualFromTree;
    
            Draw(false);
    
            var timer = new DispatcherTimer {Interval = new TimeSpan(0, 0, 2)};
            timer.Tick += (sender, args) =>
                              {
                                  Draw(true);
                                  InvalidateVisual();
                                  timer.Stop();
                              };
            timer.Start();
    
        }
    
        private void AddVisualToTree(object sender, RoutedEventArgs e)
        {
            AddVisualChild(_visual);
            AddLogicalChild(_visual);
        }
    
        private void RemoveVisualFromTree(object sender, RoutedEventArgs e)
        {
            RemoveLogicalChild(_visual);
            RemoveVisualChild(_visual);
        }
    
        3
  •  0
  •   David Jeske    8 年前

    如果你做 _visual DrawingGroup ,您可以稍后重新打开它并更改它的绘图命令,这些命令将被更新。