我的prism应用程序有许多从我的视图模型中调用的异步操作。 在某些情况下,我希望视图被禁用并显示某种忙指示符,直到viewmodel从异步操作返回结果。
我创建了一个基本视图来实现这种行为(即具有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;
}
}
}
}
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进行绑定
答案 0 :(得分: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]...; }
}
}
现在由每个特定的视图模型来决定它是否正忙。一个粗略的机制是有一个计数器,你每次启动异步函数时都会递增,并在操作结束时递减它 - 如果它的值等于零,那么就没有当前的异步操作。当使用标记或计数器时,请注意因compiler optimisations而可能发生的各种属性读取问题,请学会在正确的位置使用volatile关键字。
或者不使用计数器,您可以使用线程安全CountdownEvent class。如果你想要真正先进,那么你可以查看System.Threading namespace中的各种线程信令机制,或者查看task parallelism和Task object。