【问题标题】:Creating base loading view with prism使用棱镜创建基本加载视图
【发布时间】:2013-10-13 16:37:31
【问题描述】:

我的 prism 应用程序有很多从我的视图模型中调用的异步操作。 在某些情况下,我希望禁用视图并显示某种忙碌指示符,直到视图模型从异步操作中取回结果。

我虽然创建了一个将实现此行为的基本视图(即具有 IsLoading 的依赖属性,它将禁用该视图并在其上方显示一个忙碌指示符)。 问题是,我不确定如何实现这个基本视图。 任何帮助将不胜感激,谢谢。

编辑:我认为我写了一个 LoadingView 来完成这项工作。

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;
            }
        }
    }
}

然后我在视图模型中使用一些 IsLoading(或 IsBusy)在 LoadingView.IsLoading 上进行绑定

【问题讨论】:

    标签: c# mvvm asynchronous prism


    【解决方案1】:

    这是一个可以很快变得非常复杂的主题。

    我建议在方法上做一个小的改变——不要将 IsBusy 属性放在基础视图模型中,而是将其抽象化,以便每个派生的视图模型都必须实现自己的特定检查。

    public class BaseViewModel : INotifyPropertyChanged
    {
    
        public abstract bool IsBusy { get; }
    
    }
    
    public class FancyViewModel : BaseViewModel
    {
    
        public override bool IsBusy
        {
            get { return [check #1] && [check #2]...; }
        }
    }
    

    现在由每个特定的视图模型来确定它是否忙。一个粗略的机制是有一个计数器,每次启动异步函数时递增,并在操作结束时递减 - 如果它的值等于 0,则没有当前的异步操作。使用标志或计数器时,请注意可能因compiler optimisations 而出现的各种属性读取问题,学习在正确的位置使用 volatile 关键字。

    您也可以使用线程安全CountdownEvent class,而不是保留一个计数器。如果你想变得更高级,那么你可以查看System.Threading namespace 中的各种线程信号机制,或者查看task parallelismTask object

    【讨论】:

    • 感谢您的回答,但我的意图更多是关于视图而不是视图模型。
    • @user2853648 我知道,我的回答旨在帮助您将一堆异步方法的结果编组到一个 IsBusy 属性中。如果您仍在寻找控件,请尝试BusyIndicator
    猜你喜欢
    • 2020-10-03
    • 2021-09-07
    • 1970-01-01
    • 2019-10-18
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    相关资源
    最近更新 更多