WPF异步MVVM等待窗体

简介:

需求描述

  • 在 ViewModel 中处理 Model 中的数据需要一定时间的等待;
  • ViewModel 或 Model 在获取数据或访问同步服务时有一定延迟需要等待;
  • ViewModel 操作 View 加载数据需要一段时间;

解决办法

  • 显示一个等待 UI,当数据处理完毕或服务接口返回后等待UI消失

转动齿轮控件

等待控件

复制代码
 1   <Grid>
 2     <local:SprocketControl Grid.Row="0"
 3                            Grid.Column="0"
 4                            Width="100"
 5                            Height="100"
 6                            Margin="0,0,0,0"
 7                            HorizontalAlignment="Center"
 8                            VerticalAlignment="Center"
 9                            Background="Transparent"
10                            Interval="60"
11                            IsIndeterminate="True"
12                            StartAngle="-90"
13                            TickColor="{DynamicResource MaskForegroundColor}"
14                            TickCount="16"
15                            TickWidth="5" />
16   </Grid>
复制代码

等待效果

定义 MVVM 中的 ViewModel 的状态

复制代码
  /// <summary>
  /// 在MVVM模式中ViewModel的状态
  /// </summary>
  [Flags]
  public enum ViewModelStatus
  {
    /// <summary>
    /// ViewModel无状态
    /// </summary>
    None = 0x0,
    /// <summary>
    /// ViewModel正在初始化
    /// </summary>
    Initializing = 0x1,
    /// <summary>
    /// ViewModel初始化完毕
    /// </summary>
    Initialized = 0x2,
    /// <summary>
    /// ViewModel正在加载
    /// </summary>
    Loading = 0x4,
    /// <summary>
    /// ViewModel加载完毕
    /// </summary>
    Loaded = 0x8,
    /// <summary>
    /// ViewModel正在保存
    /// </summary>
    Saving = 0x16,
    /// <summary>
    /// ViewModel保存完毕
    /// </summary>
    Saved = 0x32
  }
复制代码

ViewModel 状态转变为控件状态

复制代码
 1   public class StatusToAnimationVisibilityConverter : IValueConverter
 2   {
 3     #region IValueConverter Members
 4 
 5     public object Convert(
 6       object value, Type targetType, object parameter, CultureInfo culture)
 7     {
 8       try
 9       {
10         string status = value.ToString();
11 
12         switch (status)
13         {
14           case "Initializing":
15           case "Loading":
16           case "Saving":
17             return Visibility.Visible;
18           case "Loaded":
19           case "Saved":
20           default:
21             return Visibility.Collapsed;
22         }
23       }
24       catch (Exception)
25       {
26         return Visibility.Collapsed;
27       }
28     }
29 
30     public object ConvertBack(
31       object value, Type targetType, object parameter, CultureInfo culture)
32     {
33       return DependencyProperty.UnsetValue;
34     }
35 
36     #endregion
37   }
复制代码

使 UserControl 支持异步显示

复制代码
 1   <coverters:StatusToAnimationVisibilityConverter x:Key="StatusToAnimationVisibilityConverter" />
 2 
 3   <Style x:Key="AsyncWorkUserControlStyle" TargetType="{x:Type UserControl}">
 4     <Setter Property="Template">
 5       <Setter.Value>
 6         <ControlTemplate TargetType="{x:Type UserControl}">
 7           <Grid>
 8             <ContentPresenter Panel.ZIndex="0" />
 9             <Grid x:Name="animationGrid"
10                   Width="Auto"
11                   Height="Auto"
12                   HorizontalAlignment="Stretch"
13                   VerticalAlignment="Stretch"
14                   Panel.ZIndex="2000"
15                   Visibility="{Binding Path=Status,
16                                Converter={StaticResource StatusToAnimationVisibilityConverter}}">
17               <Grid Width="Auto"
18                     Height="Auto"
19                     HorizontalAlignment="Stretch"
20                     VerticalAlignment="Stretch"
21                     Panel.ZIndex="0"
22                     Background="{DynamicResource MaskGridBackgroundBrush}"
23                     Opacity="0.2" />
24               <ctrl:WaitingControl x:Name="animation" Panel.ZIndex="1" />
25             </Grid>
26           </Grid>
27         </ControlTemplate>
28       </Setter.Value>
29     </Setter>
30   </Style>
复制代码

应用 Style 至 UserControl

复制代码
 1 <UserControl x:Class="DeviceConfiguration.Views.CameraManagementView"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6              d:DesignHeight="318"
 7              d:DesignWidth="632"
 8              Style="{DynamicResource AsyncWorkUserControlStyle}"
 9              mc:Ignorable="d">
10 </UserControl>
复制代码

定义基础 ViewModel

复制代码
 1   /// <summary>
 2   /// 响应式的ViewModel模型
 3   /// </summary>
 4   public abstract class ViewModelResponsive : ViewModelBase, IViewModelResponsive
 5   {
 6     #region Fields
 7 
 8     private ViewModelStatus _status = ViewModelStatus.None;
 9 
10     #endregion
11     
12     #region ViewModel Status
13 
14     /// <summary>
15     /// 刷新UI数据
16     /// </summary>
17     public virtual void Refresh()
18     {
19 
20     }
21 
22     /// <summary>
23     /// ViewModel状态
24     /// </summary>
25     public ViewModelStatus Status
26     {
27       get
28       {
29         return _status;
30       }
31       protected set
32       {
33         if (_status != value)
34         {
35           _status = value;
36           RaisePropertyChanged(@"Status");
37         }
38       }
39     }
40 
41     #endregion
42   }
复制代码

ViewModel 应用

复制代码
 1   public class CameraManagementViewModel : ViewModelResponsive
 2   {
 3     protected override void BindCommands()
 4     {
 5       RefreshCommand = new RelayCommand(() =>
 6       {
 7         Refresh();
 8       });
 9     }
10     
11     public override void Refresh()
12     {
13       base.Refresh();
14 
15       Status = ViewModelStatus.Initializing;
16       CameraCollection.Clear();
17       Model.GetCameras(GetCamerasCallback);
18     }
19     
20     private void GetCamerasCallback(object sender, AsyncWorkerCallbackEventArgs<IList<Camera>> args)
21     {
22       CameraCollection.Clear();
23       Status = ViewModelStatus.Loaded;
24 
25       if (result)
26       {
27         foreach (var item in (args.Data as IList<Camera>))
28         {
29           CameraCollection.Add(item);
30         }
31       }
32     }
33   }
复制代码

实现效果











本文转自匠心十年博客园博客,原文链接:XXXXXXXX,如需转载请自行联系原作者
目录
相关文章
|
4月前
|
设计模式 前端开发 C#
WPF 项目中 MVVM模式 的简单例子说明
本文通过WPF项目中的加法操作示例,讲解了MVVM模式的结构和实现方法,包括数据模型、视图、视图模型的创建和数据绑定,以及命令的实现和事件通知机制。
|
5月前
|
前端开发 C# 开发者
WPF开发者必读:MVVM模式实战,轻松构建可维护的应用程序,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离关注点,提高了代码的可维护性和可扩展性。本文详细介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定与逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种模式,开发者可以更高效地构建桌面应用程序。希望本文能帮助你在WPF开发中更好地应用MVVM模式。
307 1
|
5月前
|
前端开发 C# 设计模式
“深度剖析WPF开发中的设计模式应用:以MVVM为核心,手把手教你重构代码结构,实现软件工程的最佳实践与高效协作”
【8月更文挑战第31天】设计模式是在软件工程中解决常见问题的成熟方案。在WPF开发中,合理应用如MVC、MVVM及工厂模式等能显著提升代码质量和可维护性。本文通过具体案例,详细解析了这些模式的实际应用,特别是MVVM模式如何通过分离UI逻辑与业务逻辑,实现视图与模型的松耦合,从而优化代码结构并提高开发效率。通过示例代码展示了从模型定义、视图模型管理到视图展示的全过程,帮助读者更好地理解并应用这些模式。
138 0
|
5月前
|
前端开发 开发者 C#
WPF开发者必读:MVVM模式实战,轻松实现现代桌面应用架构,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离应用程序的逻辑和界面,提高了代码的可维护性和可扩展性。本文介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定和逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种方式,开发者可以构建更加高效和可扩展的桌面应用程序。
260 0
|
5月前
|
设计模式 前端开发 C#
WPF/C#:理解与实现WPF中的MVVM模式
WPF/C#:理解与实现WPF中的MVVM模式
317 0
|
设计模式 开发框架 前端开发
深入理解WPF中MVVM的设计思想
近些年来,随着WPF在生产,制造,工业控制等领域应用越来越广发,很多企业对WPF开发的需求也逐渐增多,使得很多人看到潜在机会,不断从Web,WinForm开发转向了WPF开发,但是WPF开发也有很多新的概念及设计思想,如:数据驱动,数据绑定,依赖属性,命令,控件模板,数据模板,MVVM等,与传统WinForm,ASP.NET WebForm开发,有很大的差异,今天就以一个简单的小例子,简述WPF开发中MVVM设计思想及应用。
118 0
|
前端开发
WPF-Binding问题-MVVM中IsChecked属性CommandParameter转换值类型空异常
WPF-Binding问题-MVVM中IsChecked属性CommandParameter转换值类型空异常
215 0
|
前端开发 算法 JavaScript
走进WPF之MVVM完整案例
走进WPF之MVVM完整案例
274 0
WPF控件和窗体一起放大一起缩小
WPF控件和窗体一起放大一起缩小
266 0
|
C# 容器
WPF框架下,窗体的嵌套显示
WPF框架下,窗体的嵌套显示
242 0