欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于WPF异步MVVM等待窗体的介绍

程序员文章站 2023-12-13 10:49:46
需求描述•在viewmodel中处理model中的数据需要一定时间的等待•viewmodel或model在获取数据或访问同步服务时有一定延迟需要等待...

需求描述
•在viewmodel中处理model中的数据需要一定时间的等待
•viewmodel或model在获取数据或访问同步服务时有一定延迟需要等待
•viewmodel操作view加载数据需要一段时间
解决办法
•显示一个等待ui,当数据处理完毕或服务接口返回后等待ui消失
转动齿轮控件
•参考开源实现sprocketcontrol :http://wpfspark.codeplex.com/
等待控件

复制代码 代码如下:

<grid>
     <local:sprocketcontrol grid.row="0"
                            grid.column="0"
                            width="100"
                            height="100"
                            margin="0,0,0,0"
                            horizontalalignment="center"
                            verticalalignment="center"
                            background="transparent"
                            interval="60"
                            isindeterminate="true"
                            startangle="-90"
                            tickcolor="{dynamicresource maskforegroundcolor}"
                            tickcount="16"
                            tickwidth="5" />
   </grid>

等待效果

关于WPF异步MVVM等待窗体的介绍

定义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状态转变为控件状态
复制代码 代码如下:

public class statustoanimationvisibilityconverter : ivalueconverter
   {
     #region ivalueconverter members

     public object convert(
       object value, type targettype, object parameter, cultureinfo culture)
     {
       try
       {
         string status = value.tostring();

         switch (status)
         {
           case "initializing":
           case "loading":
           case "saving":
             return visibility.visible;
           case "loaded":
           case "saved":
           default:
             return visibility.collapsed;
         }
       }
       catch (exception)
       {
         return visibility.collapsed;
       }
     }

     public object convertback(
       object value, type targettype, object parameter, cultureinfo culture)
     {
       return dependencyproperty.unsetvalue;
     }

     #endregion
   }

使usercontrol支持异步显示
复制代码 代码如下:

<coverters:statustoanimationvisibilityconverter x:key="statustoanimationvisibilityconverter" />

   <style x:key="asyncworkusercontrolstyle" targettype="{x:type usercontrol}">
     <setter property="template">
       <setter.value>
         <controltemplate targettype="{x:type usercontrol}">
           <grid>
             <contentpresenter panel.zindex="0" />
             <grid x:name="animationgrid"
                   width="auto"
                   height="auto"
                   horizontalalignment="stretch"
                   verticalalignment="stretch"
                   panel.zindex="2000"
                   visibility="{binding path=status,
                                converter={staticresource statustoanimationvisibilityconverter}}">
               <grid width="auto"
                     height="auto"
                     horizontalalignment="stretch"
                     verticalalignment="stretch"
                     panel.zindex="0"
                     background="{dynamicresource maskgridbackgroundbrush}"
                     opacity="0.2" />
               <ctrl:waitingcontrol x:name="animation" panel.zindex="1" />
             </grid>
           </grid>
         </controltemplate>
       </setter.value>
     </setter>
   </style>

应用style至usercontrol
复制代码 代码如下:

<usercontrol x:class="deviceconfiguration.views.cameramanagementview"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              d:designheight="318"
              d:designwidth="632"
              style="{dynamicresource asyncworkusercontrolstyle}"
              mc:ignorable="d">
 </usercontrol>

定义基础viewmodel
复制代码 代码如下:

/// <summary>
   /// 响应式的viewmodel模型
   /// </summary>
   public abstract class viewmodelresponsive : viewmodelbase, iviewmodelresponsive
   {
     #region fields

     private viewmodelstatus _status = viewmodelstatus.none;

     #endregion

     #region viewmodel status

     /// <summary>
     /// 刷新ui数据
     /// </summary>
     public virtual void refresh()
     {

     }

     /// <summary>
     /// viewmodel状态
     /// </summary>
     public viewmodelstatus status
     {
       get
       {
         return _status;
       }
       protected set
       {
         if (_status != value)
         {
           _status = value;
           raisepropertychanged(@"status");
         }
       }
     }

     #endregion
   }

viewmodel应用
复制代码 代码如下:

public class cameramanagementviewmodel : viewmodelresponsive
   {
     protected override void bindcommands()
     {
       refreshcommand = new relaycommand(() =>
       {
         refresh();
       });
     }

     public override void refresh()
     {
       base.refresh();

       status = viewmodelstatus.initializing;
       cameracollection.clear();
       model.getcameras(getcamerascallback);
     }

     private void getcamerascallback(object sender, asyncworkercallbackeventargs<ilist<camera>> args)
     {
       cameracollection.clear();
       status = viewmodelstatus.loaded;

       if (result)
       {
         foreach (var item in (args.data as ilist<camera>))
         {
           cameracollection.add(item);
         }
       }
     }
   }

关于WPF异步MVVM等待窗体的介绍

上一篇:

下一篇: