简体   繁体   中英

Creating base loading view with prism

My prism application has a lot of async operations called from my view models. In some cases, I want the view to be disabled and display some kind of busy indicator until the viewmodel gets back the result from the async operation.

I though of creating a base view which will implement this behavior (ie have a dependency property of IsLoading which will disable the view and display a busy indicator above it). The problem is, I'm not sure how to implement this base view. Any help would be appreciated, thanks.

Edit: I wrote a LoadingView which does the job, I think.

public class LoadingView : UserControl { private object content;

  public bool IsLoading { get { return (bool)GetValue(IsLoadingProperty); } set { SetValue(IsLoadingProperty, value); } } private ProgressRing m_RingControl; public LoadingView() { m_RingControl = new ProgressRing(); m_RingControl.IsActive = false; } // Using a DependencyProperty as the backing store for IsLoading. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsLoadingProperty = DependencyProperty.Register("IsLoading", typeof(bool), typeof(LoadingView), new PropertyMetadata(false, IsActivePropertyChanged)); private static void IsActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { LoadingView view = d as LoadingView; if (view != null) { // Loading - show ring control if (((bool)e.NewValue) == true) { view.content = view.Content; view.Content = view.m_RingControl; view.m_RingControl.IsActive = true; } else { view.m_RingControl.IsActive = false; view.Content = view.content; } } } } 

and i put binding on LoadingView.IsLoading with some IsLoading (or IsBusy) in the viewmodel

This is a subject that can get really complex really fast.

I would advise a small change in approach - instead of putting an IsBusy property in a base viewmodel, instead make it abstract so that each derived viewmodel has to implement its own specific check.

public class BaseViewModel : INotifyPropertyChanged
{

    public abstract bool IsBusy { get; }

}

public class FancyViewModel : BaseViewModel
{

    public override bool IsBusy
    {
        get { return [check #1] && [check #2]...; }
    }
}

Now it is up to each specific viewmodel to determine whether it is busy. A crude mechanism is to have a counter which you increment every time an async function is kicked off, and decrement it when the operation ends - if its value is equal to zero then there are no current async operations. When using flags or counters be aware of various property reading issues that can occur because of compiler optimisations , learn to use the volatile keyword in the right place.

Alternatively instead of keeping a counter you could use the thread safe CountdownEvent class . If you want to get really advanced then you can check out the various thread signalling mechanisms in the System.Threading namespace , or look at task parallelism and the Task object .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM