zl程序教程

您现在的位置是:首页 >  后端

当前栏目

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

WPF异步 介绍 关于 等待 窗体 MVVM
2023-06-13 09:14:50 时间

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

复制代码代码如下:

<Grid>
    <local:SprocketControlGrid.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="{DynamicResourceMaskForegroundColor}"
                           TickCount="16"
                           TickWidth="5"/>
  </Grid>

等待效果

定义MVVM中的ViewModel的状态

复制代码代码如下:

///<summary>
 ///在MVVM模式中ViewModel的状态
 ///</summary>
 [Flags]
 publicenumViewModelStatus
 {
   ///<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状态转变为控件状态
复制代码代码如下:
publicclassStatusToAnimationVisibilityConverter:IValueConverter
  {
    #regionIValueConverterMembers

    publicobjectConvert(
      objectvalue,TypetargetType,objectparameter,CultureInfoculture)
    {
      try
      {
        stringstatus=value.ToString();

        switch(status)
        {
          case"Initializing":
          case"Loading":
          case"Saving":
            returnVisibility.Visible;
          case"Loaded":
          case"Saved":
          default:
            returnVisibility.Collapsed;
        }
      }
      catch(Exception)
      {
        returnVisibility.Collapsed;
      }
    }

    publicobjectConvertBack(
      objectvalue,TypetargetType,objectparameter,CultureInfoculture)
    {
      returnDependencyProperty.UnsetValue;
    }

    #endregion
  }

使UserControl支持异步显示
复制代码代码如下:
<coverters:StatusToAnimationVisibilityConverterx:Key="StatusToAnimationVisibilityConverter"/>

  <Stylex:Key="AsyncWorkUserControlStyle"TargetType="{x:TypeUserControl}">
    <SetterProperty="Template">
      <Setter.Value>
        <ControlTemplateTargetType="{x:TypeUserControl}">
          <Grid>
            <ContentPresenterPanel.ZIndex="0"/>
            <Gridx:Name="animationGrid"
                  Width="Auto"
                  Height="Auto"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  Panel.ZIndex="2000"
                  Visibility="{BindingPath=Status,
                               Converter={StaticResourceStatusToAnimationVisibilityConverter}}">
              <GridWidth="Auto"
                    Height="Auto"
                    HorizontalAlignment="Stretch"
                    VerticalAlignment="Stretch"
                    Panel.ZIndex="0"
                    Background="{DynamicResourceMaskGridBackgroundBrush}"
                    Opacity="0.2"/>
              <ctrl:WaitingControlx:Name="animation"Panel.ZIndex="1"/>
            </Grid>
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>

应用Style至UserControl
复制代码代码如下:
<UserControlx: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="{DynamicResourceAsyncWorkUserControlStyle}"
             mc:Ignorable="d">
 </UserControl>

定义基础ViewModel
复制代码代码如下:
///<summary>
  ///响应式的ViewModel模型
  ///</summary>
  publicabstractclassViewModelResponsive:ViewModelBase,IViewModelResponsive
  {
    #regionFields

    privateViewModelStatus_status=ViewModelStatus.None;

    #endregion

    #regionViewModelStatus

    ///<summary>
    ///刷新UI数据
    ///</summary>
    publicvirtualvoidRefresh()
    {

    }

    ///<summary>
    ///ViewModel状态
    ///</summary>
    publicViewModelStatusStatus
    {
      get
      {
        return_status;
      }
      protectedset
      {
        if(_status!=value)
        {
          _status=value;
          RaisePropertyChanged(@"Status");
        }
      }
    }

    #endregion
  }

ViewModel应用
复制代码代码如下:
publicclassCameraManagementViewModel:ViewModelResponsive
  {
    protectedoverridevoidBindCommands()
    {
      RefreshCommand=newRelayCommand(()=>
      {
        Refresh();
      });
    }

    publicoverridevoidRefresh()
    {
      base.Refresh();

      Status=ViewModelStatus.Initializing;
      CameraCollection.Clear();
      Model.GetCameras(GetCamerasCallback);
    }

    privatevoidGetCamerasCallback(objectsender,AsyncWorkerCallbackEventArgs<IList<Camera>>args)
    {
      CameraCollection.Clear();
      Status=ViewModelStatus.Loaded;

      if(result)
      {
        foreach(varitemin(args.DataasIList<Camera>))
        {
          CameraCollection.Add(item);
        }
      }
    }
  }