我可以在让用户等待之前更新WPF StatusBar文本吗?

Zac*_*son 4 .net wpf multithreading statusbar backgroundworker

我有一个带状态栏的WPF应用程序.

<StatusBar Grid.Row="1"
           Height="23"
           Name="StatusBar1"
           VerticalAlignment="Bottom">
    <TextBlock Name="TextBlockStatus" />
</StatusBar>
Run Code Online (Sandbox Code Playgroud)

我想在那里显示文本并在我做少量工作时切换到沙漏等待光标.

此代码将更新光标,但StatusBar 文本不会更新 ...

Cursor = Cursors.Wait
TextBlockStatus.Text = "Loading..."
System.Threading.Thread.Sleep(New TimeSpan(0, 0, 3))
TextBlockStatus.Text = String.Empty
Cursor = Cursors.Arrow
Run Code Online (Sandbox Code Playgroud)

更新

灵感来自亚历山德拉答案 ......

如果我这样做的话,它会起作用,但我对这个解决方案并不满意.有更简单的方法吗?

Delegate Sub Load1()
Sub Load2()
    System.Threading.Thread.Sleep(New TimeSpan(0, 0, 3))
End Sub
Dim Load3 As Load1 = AddressOf Load2

Sub Load()
    Cursor = Cursors.Wait
    TextBlockStatus.Text = "Loading..."
    Dispatcher.Invoke(DispatcherPriority.Background, Load3)
    TextBlockStatus.Text = String.Empty
    Cursor = Cursors.Arrow
End Sub
Run Code Online (Sandbox Code Playgroud)

我宁愿它看起来像这样......

Sub Load()
    Cursor = Cursors.Wait
    TextBlockStatus.Text = "Loading..."

    'somehow put all the Dispatcher, Invoke, Delegate,
     AddressOf, and method definition stuff here'

    TextBlockStatus.Text = String.Empty
    Cursor = Cursors.Arrow
End Sub
Run Code Online (Sandbox Code Playgroud)

甚至更好......

Sub Load()
    Cursor = Cursors.Wait
    ForceStatus("Loading...")
    System.Threading.Thread.Sleep(New TimeSpan(0, 0, 3))
    ForceStatus(String.Empty)
    Cursor = Cursors.Arrow
End Sub

Sub ForceStatus(ByVal Text As String)
    TextBlockStatus.Text = Text
    'perform magic'
End Sub
Run Code Online (Sandbox Code Playgroud)

更新

我还尝试将TextBlock绑定到公共属性,并按照IanGilham的建议实现INotifyPropertyChanged.这不起作用.

XAML:

<TextBlock Text="{Binding Path=StatusText}"/>
Run Code Online (Sandbox Code Playgroud)

Visual Basic:

Imports System.ComponentModel
Partial Public Class Window1
    Implements INotifyPropertyChanged

    Private _StatusText As String = String.Empty
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    Property StatusText() As String
        Get
            Return _StatusText
        End Get
        Set(ByVal value As String)
            _StatusText = value
            OnPropertyChanged("StatusText")
        End Set
    End Property

    Shadows Sub OnPropertyChanged(ByVal name As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
    End Sub
    ...

    Sub Load()
        ...
        Cursor = Cursors.Wait
        StatusText = "Loading..."
        System.Threading.Thread.Sleep(New TimeSpan(0, 0, 3))
        StatusText = String.Empty
        Cursor = Cursors.Arrow
        ...
    End Sub
...
Run Code Online (Sandbox Code Playgroud)

Ran*_*ngy 5

您应该使用BackgroundWorker.该工作将发生一个单独的线程,这意味着您的UI线程将是免费的,您的应用程序仍将是响应.

它不会是一个代码非常紧凑的解决方案,但它对用户来说是最强大和最友好的.