【问题标题】:wpf forcing update UI window during a procedurewpf 在过程中强制更新 UI 窗口
【发布时间】:2011-04-16 09:45:15
【问题描述】:

如果我使用文件 .cur 或 .ani 来替换鼠标光标,我只需要显示一个自定义控件(带有旋转指针的时钟)并用它来替换鼠标光标 Me.CUrsor = New Cursor(".ani 文件的绝对路径") 没有问题:我可以在一个过程中改变光标:但是动画质量很差,而且,还有其他原因,我更喜欢使用我的小用户控件。问题是,如果我写:

Me.gridScreen.Visibility = Visibility.Visible

' 一些大约需要 1 秒的操作

Me.gridScreen.Visibility = Visibility.Hidden

(gridScreen 是包含用户控件的网格)

显然我什么也看不到,因为 UI 的更新发生在程序结束时。我已经尝试过 Me.UpdateLayout(),但它不起作用。

我尝试过以多种方式使用拆包器,但都没有用 :-(

这是我失败的尝试:

(uCurClock是用户控件,gridScreen是一个放置在窗口顶层的Grid,背景透明,包含用户控件)

Private Sub showClock()G
    Dim thread = New System.Threading.Thread(AddressOf showClockIntermediate)
    thread.Start()
End Sub

Private Sub hideClock()
    Dim thread = New System.Threading.Thread(AddressOf hideClockIntermediate)
    thread.Start()
End Sub

Private Sub showClockIntermediate()
    Me.Dispatcher.BeginInvoke(DispatcherPriority.Normal, New Action(AddressOf showClockFinale))
End Sub

Private Sub hideClockIntermediate()
    Me.Dispatcher.BeginInvoke(DispatcherPriority.Normal, New Action(AddressOf hideClockFinale))
End Sub

Private Sub showClockFinale()
    Dim pt As Point = Mouse.GetPosition(Nothing)
    Me.uCurClock.Margin = New Thickness(pt.X - 9, pt.Y - 9, 0, 0)
    Me.gridScreen.Visibility = Visibility.Visible
    Me.Cursor = Cursors.None
    Me.UpdateLayout()
End Sub

Private Sub hideClockFinale()
    Me.gridScreen.Visibility = Visibility.Hidden
    Me.Cursor = Cursors.Arrow
    Me.UpdateLayout()
End Sub

Private Sub u_MouseMove(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles gridScreen.MouseMove
    Dim pt As Point = e.GetPosition(Nothing)
    Me.uCurClock.Margin = New Thickness(pt.X - 9, pt.Y - 9, 0, 0)

    e.Handled = True
End Sub

Private Sub u_MouseEnter(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles gridScreen.MouseEnter
    Me.uCurClock.Visibility = Visibility.Visible

    e.Handled = True
End Sub

Private Sub u_MouseLeave(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles gridScreen.MouseLeave
    Me.uCurClock.Visibility = Visibility.Hidden

    e.Handled = True
End Sub

皮莱吉

【问题讨论】:

    标签: wpf multithreading user-interface refresh


    【解决方案1】:

    虽然以下代码可以满足您的要求,但我怀疑它实际上对您没有帮助,因为您提到了动画。您将需要使用多个线程。但是,为了说明原因,以下内容可以回答您提出的问题:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
    
        uc1.Visibility = Visibility.Visible
        Cursor = Cursors.Wait
    
        ' Push visibility changes now.
        ' (Sort of like DoEvents - and a horrible idea for exactly the same
        ' reasons that DoEvents was a total train wreck. Never actually do
        ' this - use a background thread instead.)
        Dim df As New DispatcherFrame(True)
        Dispatcher.BeginInvoke(Sub() df.Continue = False, DispatcherPriority.ContextIdle)
        Dispatcher.PushFrame(df)
    
        Thread.Sleep(1000)
    
        ClearValue(CursorProperty)
        uc1.Visibility = Visibility.Hidden
    
    End Sub
    

    假设您在页面上有一些名为 uc1 的用户控件,这将强制它在您的慢速程序运行时可见。

    但不会运行任何动画。问题是,如果你在 UI 线程上做一些缓慢的事情,UI 线程就不能做任何其他事情——它不能运行动画,它不能响应用户输入。基本上用户界面被冻结了。此处显示的代码甚至使用户控件可见的唯一原因是它基本上说“立即执行任何未完成的 UI 线程工作”,这具有处理您对 Visible 属性的更改的副作用。

    但动画也发生在 UI 线程上。

    如果您想正确执行此操作,则需要在后台线程上完成工作,可能通过使用 BackgroundWorker 或编写您自己的线程代码。

    【讨论】:

    • Griffitshs:谢谢!我使用了 .ani 光标,但你的反应很有趣!
    【解决方案2】:

    参考DispatcherFrame Class Reference

    好 ole DoEvents 用于 WPF !!!

    Public Sub DoEvents()
        Dim frame As New DispatcherFrame()
        Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, New DispatcherOperationCallback(AddressOf ExitFrame), frame)
        Dispatcher.PushFrame(frame)
    End Sub
    
    Public Function ExitFrame(ByVal f As Object) As Object
        CType(f, DispatcherFrame).Continue = False
        Return Nothing
    End Function
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-09
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多