关于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);
}
}
}
}
相关文章
- WPF AvalonDock拖拽布局学习整理
- wpf绘图性能分析
- WPF实现列表分页控件的示例代码分享
- WPF 依赖注入之 Microsoft.Extensions.DependencyInjection
- 开源C# WPF控件库《MaterialDesignInXAML》强力推荐
- WPF ComboBox 使用 ResourceBinding 动态绑定资源键并支持语言切换
- WPF 表单验证之 INotifyDataErrorlnfo 接口的使用示例
- WPF 实现带明细的环形图表
- 06Prism WPF 入门实战 - Log&控件库
- 解读WPF中的Binding
- WPF中用户控件和自定义控件
- .NET + WPF框架开发聊天、网盘、信息发布、视频播放功能
- 【愚公系列】2023年02月 .NET CORE工具案例-MahApps.Metro基于WPF的UI控件库
- WPF 已知问题 dotnet 6 设置 InvariantGlobalization 之后将丢失默认绑定转换导致 XAML 抛出异常
- WPF连接MySQL:实现跨平台的数据交互(wpf 连接mysql)
- WPF连接MySQL:实现步骤深度剖析(wpf 连接mysql)
- WPF驱动下的MySQL持续优化与发展(c wpf mysql)
- 关于WPF使用MultiConverter控制Button状态的详细介绍