我创建自己的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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
InvalidateVisual()什么也没做.虽然如果您调整包含该元素的窗口的大小,它会更新.
有关如何正确刷新内容的任何想法?最好不要为我的元素引入新的依赖属性.
加
this.AddVisualChild(_visual);
this.AddLogicalChild(_visual);
Run Code Online (Sandbox Code Playgroud)
到TestControl类的构造函数.
基于SMART_n的答案,这是一个不会泄漏内存的改进解决方案:
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2846 次 |
| 最近记录: |