关于WPF异步MVVM等待窗体的介绍_C#教程-查字典教程网
关于WPF异步MVVM等待窗体的介绍
关于WPF异步MVVM等待窗体的介绍
发布时间:2016-12-28 来源:查字典编辑
摘要:需求描述•在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>

等待效果

定义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"

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

}

}

}

}

相关阅读
推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  • 最新C#教程学习
    热门C#教程学习
    编程开发子分类