Frage

Is it ever possible that UI skips updating itself although the Visibility of the UI component is binded to ViewModel property and PropertyChanged for that property is implemented?

View/XAML:

 <Border Visibility="{Binding ShowLoadingPanel, Converter={StaticResource BoolToHiddenConverter}}">
      <TextBlock Text="LOADING..." />
 </Border>

ViewModel:

Public Property ShowLoadingPanel As Boolean
    Get
        Return _showLoadingPanel
    End Get
    Set(value As Boolean)
        _showLoadingPanel = value
        OnPropertyChanged("ShowLoadingPanel")
    End Set
End Property

When running the following from ViewModel:

 ShowLoadingPanel = True
 RunBigTask()  'runs a task that takes a long time
 ShowLoadingPanel = False

...the Border defined in XAML doesn't become visible.

But if I add something requiring user interaction, for example like:

 ShowLoadingPanel = True
 MsgBox("Click to continue")
 RunBigTask()  'runs a task that takes a long time
 ShowLoadingPanel = False

... then the border becomes visible as desired.

How is that possible?

War es hilfreich?

Lösung 2

You are blocking the Dispatcher, preventing the layout from being updated. When you open a Message Box, you push a nested message loop that allows the Dispatcher to continue processing its queue until the Message Box is closed. The layout updates are happening during that period.

The same thing happens when you call ShowDialog() on a regular Window: your code blocks, but the Dispatcher keeps running so the UI updates as expected. Your code does not resume until the nested message loop is popped, which happens automatically when you close a modal dialog (like your Message Box).

Andere Tipps

You should really run your long running task in a background thread because it is blocking your UI thread from updating the Visibility... as it is, the Visibility should update when the long running task is complete.

It is quite common for users to use a BackgroundWorker object to do this. You can find a complete working example on the BackgroundWorker Class page on MSDN.

A common alternative to the BackgroundWorker would be to use a Task object to run your long running process asynchronously. You can find a full working example of using a Task on the Task Class page on MSDN.

I'm using C#, and in our case Visiblity is not a boolean, but an enum: System.Windows.Visibility with values of Hidden / Visible/ Collapsed.

The same seems true for VB : Public Property Visibility As Visibility

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top