我有一个Silverlight应用程序,上面有一个Canvas。 在那个Canvas上,我动态地“绘制”了一堆东西,但是在画布上添加了控件。
我在Canvas区域外有一个按钮可以清除内容。 删除对象(成功)。但是,Canvas区域不会立即刷新;它目前需要一个MouseOver或Canvas本身的其他事件。
让外部对象使Canvas无效的最简单方法是什么?我确定我错过了一些简单的东西!
答案 0 :(得分:4)
这有点肮脏,但您可以尝试将可见性更改为Canvas的'Visible'(即使它已经是),所以:
myCanvas.Visibility = Visibility.Visible;
我们发现这会强制重绘,即使myCanvas.Visible的实际值没有改变......
试一试,它只是一个可以解决问题的衬垫。虽然我希望Canvas能够重新绘制,如果你要从中删除它。
答案 1 :(得分:1)
如果有人在事后出现,就像我一直在寻找这个答案那样......
yourFrameworkElement.InvalidateArrange();
yourFrameworkElement.UpdateLayout();
为我工作。
注意:仅调用this.yourFrameworkElement.UpdateLayout();
不为我工作。我不得不打电话给InvalidateArrange()
。我之后立即致电UpdateLayout()
以获得完整性 - 可能没有实际影响。
同样,myCanvas.Visibility = Visibility.Visible;
技巧对我不起作用,因为我试图触发LayoutUpdated事件。
答案 2 :(得分:1)
不是简单的单行,但它有效。它在我的经验中运作良好。它将给定的操作推迟了十分之一秒以允许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.
});
答案 3 :(得分:0)
在我的情况下(我在Canvas中有一个Canvas,我需要通过方向更改来调整内部画布的大小),myCanvas.Visibility = Visibility.Visible;
技巧没有做到,但它真的很接近:
myCanvas.Visibility = Visibility.Collapsed;
myCanvas.Visibility = Visibility.Visible;
工作得很好。
InvalidateArrange
后跟UpdateLayout
也没有这样做。
最后,所有这一切都没有必要,因为我意识到Canvas中的Canvas不是必需的,并且能够为StackPanel更改内部Canvas,并且不需要任何技巧来使其按预期工作。