【问题标题】:Silverlight: Force Canvas to Invalidate or Repaint itself?Silverlight:强制 Canvas 使其自身无效或重绘?
【发布时间】:2009-01-30 22:34:19
【问题描述】:

我有一个 Silverlight 应用程序,上面有一个 Canvas。 在那个画布上,我动态地“绘制”了一堆东西,但在画布上添加了控件。

我在画布区域外有一个按钮,用于清除内容。 对象被移除(成功)。但是,Canvas 区域不会立即自行刷新;它目前需要画布本身的 MouseOver 或其他事件。

让外部对象使 Canvas 无效的最简单方法是什么?我确定我错过了一些简单的东西!

【问题讨论】:

    标签: silverlight-2.0


    【解决方案1】:

    这有点脏,但您可以尝试将 Canvas 的可见性更改为“可见”(即使它已经是),所以:

    myCanvas.Visibility = Visibility.Visible;
    

    我们发现这会强制重绘,即使 myCanvas.Visible 的实际值没有改变......

    试一试,它只是一个可以解决问题的班轮。尽管如果您要从中删除内容,我希望 Canvas 无论如何都会重新绘制。

    【讨论】:

    • 不知何故,我的问题自己解决了。但是,这个答案非常好,因为它的影响非常低。我可能会将其添加到我的代码中作为防御措施。
    【解决方案2】:

    如果有人像我一样在寻找这个答案之后出现......

    yourFrameworkElement.InvalidateArrange();
    yourFrameworkElement.UpdateLayout();
    

    为我工作。

    注意:只打电话给this.yourFrameworkElement.UpdateLayout(); 对我没有工作。我不得不打电话给InvalidateArrange()。为了完整起见,我立即致电UpdateLayout() - 实际影响可能为零。

    myCanvas.Visibility = Visibility.Visible; 技巧也对我不起作用,因为我试图触发 LayoutUpdated 事件。

    【讨论】:

    • 没有导致我重新粉刷。这似乎不是这个问题的解决方案。
    【解决方案3】:

    不是一个简单的单行,但它有效。根据我的经验,它运作良好。它将给定的动作推迟十分之一秒以允许 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.
        });
    

    【讨论】:

      【解决方案4】:

      在我的例子中(我在 Canvas 中有一个 Canvas,由于方向变化,我需要调整内部画布的大小),myCanvas.Visibility = Visibility.Visible; 技巧没有做到这一点,但它真的很接近:

      myCanvas.Visibility = Visibility.Collapsed;
      myCanvas.Visibility = Visibility.Visible;
      

      工作得很好。

      InvalidateArrange 后跟 UpdateLayout 也没有这样做。

      最后,所有这些都不是必需的,因为我意识到 Canvas 中的 Canvas 不是必需的,并且能够更改 StackPanel 的内部 Canvas,并且不需要任何技巧就可以按预期工作。

      【讨论】:

        猜你喜欢
        • 2013-11-03
        • 2011-10-19
        • 1970-01-01
        • 1970-01-01
        • 2016-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多