我有一个 Silverlight 应用程序,上面有一个 Canvas。在那个画布上,我动态地“绘制”了一堆东西,但在画布上添加了控件。
我在 Canvas 区域外有一个按钮,用于清除内容。对象被移除(成功)。但是,Canvas 区域不会立即自行刷新;它目前需要画布本身的 MouseOver 或其他事件。
让外部对象使 Canvas 无效的最简单方法是什么?我确定我错过了一些简单的东西!
我有一个 Silverlight 应用程序,上面有一个 Canvas。在那个画布上,我动态地“绘制”了一堆东西,但在画布上添加了控件。
我在 Canvas 区域外有一个按钮,用于清除内容。对象被移除(成功)。但是,Canvas 区域不会立即自行刷新;它目前需要画布本身的 MouseOver 或其他事件。
让外部对象使 Canvas 无效的最简单方法是什么?我确定我错过了一些简单的东西!
这有点肮脏,但您可以尝试将 Canvas 的可见性更改为“可见”(即使它已经是),所以:
myCanvas.Visibility = Visibility.Visible;
我们发现这会强制重绘,即使 myCanvas.Visible 的实际值没有改变......
试一试,它只是一个可以解决问题的班轮。尽管如果您要从中删除内容,我希望 Canvas 无论如何都会重新绘制。
万一有人像我一样在寻找这个答案之后出现......
yourFrameworkElement.InvalidateArrange();
yourFrameworkElement.UpdateLayout();
为我工作。
注意:只打电话对this.yourFrameworkElement.UpdateLayout();
我不起作用。我不得不打电话InvalidateArrange()
。此后我立即致电UpdateLayout()
以求完整性-可能实际影响为零。
这个myCanvas.Visibility = Visibility.Visible;
技巧也对我不起作用,因为我试图触发 LayoutUpdated 事件。
不是一个简单的单线,但它的工作原理。根据我的经验,它运作良好。它将给定的动作推迟十分之一秒以允许 UI 线程更新,但它仍然在 UI 线程上执行该动作。
using System;
using System.Windows.Threading;
public static class MyTestClass
{
public static void Postpone(Action a_action)
{
TaggedDispatchTimer timer = new TaggedDispatchTimer();
timer.Interval = TimeSpan.FromSeconds(0.1);
timer.Tick += OnDoPostponedAction;
timer.UserState = a_action;
timer.Start();
}
private static void OnDoPostponedAction(object sender, EventArgs e)
{
TaggedDispatchTimer timer = sender as TaggedDispatchTimer;
timer.Stop();
timer.Tick -= OnDoPostponedAction;
var action = timer.UserState as Action;
if (action != null)
action();
}
}
public class TaggedDispatchTimer : DispatcherTimer
{
public Object UserState { get; set; }
}
这是我如何使用它:
MyTestClass.Postpone(() =>
{
// Do some bloody long operation.
});
在我的情况下(我在 Canvas 中有一个 Canvas 并且由于方向变化我需要调整内部画布的大小),这个myCanvas.Visibility = Visibility.Visible;
技巧没有做到,但它真的很接近:
myCanvas.Visibility = Visibility.Collapsed;
myCanvas.Visibility = Visibility.Visible;
工作得很好。
InvalidateArrange
后面的an也UpdateLayout
没有做到。
最后,这一切都不是必需的,因为我意识到 Canvas 中的 Canvas 不是必需的,并且能够更改 StackPanel 的内部 Canvas,并且不需要任何技巧就可以按预期工作。