WPF 簡易耗時載入進度條
阿新 • • 發佈:2018-12-19
本文實現了簡易的WPF載入進度條,其MVVM框架基於Caliburn.Micro 3.2.0,相關框架的知識請自行百度學習。
- 建立BaseViewModel基類,基類繼承自Caliburn.Micro的PropertyChangedBase類(該類實現了INotifyPropertyChanged介面,省去了自己實現介面的過程)。BaseViewModel類中定義了兩個委託,委託ShowLodingEvent用於顯示載入進度條,委託CloseLoadingEvent用於關閉載入進度
/// <summary> /// ViewModel的基類 /// </summary> public class BaseViewModel : PropertyChangedBase { #region 委託 /// <summary> /// 顯示載入進度條 /// </summary> public Action<string> ShowLodingEvent { get; set; } /// <summary> /// 關閉載入進度條 /// </summary> public System.Action CloseLoadingEvent { get; set; } #endregion }
- 建立載入進度條彈窗 LoadingDialog (借鑑LisenYang的彈窗 https://blog.csdn.net/lisenyang/article/details/18218167)
前臺XAML程式碼如下
<Window x:Class="LovelyWpf.BaseView.LoadingDialog" 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" xmlns:local="clr-namespace:LovelyWpf.BaseView" mc:Ignorable="d" Background="Transparent" WindowStyle="None" AllowsTransparency="True" Opacity="0.5" Width="300" Height="140"> <Window.Resources> <Storyboard x:Key="Storyboard1"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" RepeatBehavior="Forever" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.Opacity)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse1"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.1000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse2"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.7000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.2000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse3"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.3000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse4"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.4000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse5"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.5000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse6"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.7000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.1000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.6000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse7"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.2000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.7000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse8"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.3000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.8000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse9"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.4000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.9000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse10"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.1000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.5000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:02" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse11"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.2000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.6000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:02.1000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse12"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.3000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.7000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:02.2000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse13"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.4000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.8000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:02.3000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse14"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.5000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.9000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:02.4000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse15"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.6000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:02.5000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse16"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.7000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.1000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:02.6000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" Storyboard.TargetName="ellipse17"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.8000000" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02.2000000" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:02.7000000" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" RepeatBehavior="Forever" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="180" /> <SplineDoubleKeyFrame KeyTime="00:00:01" Value="360" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" RepeatBehavior="Forever" Storyboard.TargetName="border1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:02" Value="180" /> <SplineDoubleKeyFrame KeyTime="00:00:04" Value="360" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </Window.Resources> <Window.Triggers> <EventTrigger RoutedEvent="FrameworkElement.Loaded"> <BeginStoryboard Storyboard="{StaticResource Storyboard1}" /> </EventTrigger> </Window.Triggers> <Grid x:Name="LayoutRoot" Background="#00000000"> <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="40"></RowDefinition> </Grid.RowDefinitions> <Viewbox Width="8" Height="8" Grid.Row="0"> <Grid HorizontalAlignment="Center" x:Name="loading" Margin="0" VerticalAlignment="Center" Width="3.333" Height="3.333" Visibility="Visible"> <Ellipse RenderTransformOrigin="0.468,3.443" x:Name="ellipse" Fill="RoyalBlue" Stroke="{x:Null}" d:IsHidden="True" /> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse1" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="20" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse2" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="40" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse3" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="60" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse4" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="80" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse5" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="100" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse6" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="120" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse7" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="140" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse8" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="160" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse9" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="180" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse10" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="200" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse11" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="220" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse12" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="240" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse13" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="260" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse14" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="280" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse15" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="300" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse16" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="320" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.468,3.443" Fill="RoyalBlue" Stroke="{x:Null}" x:Name="ellipse17" d:IsHidden="True"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="340" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse RenderTransformOrigin="0.5,0.499" x:Name="ellipse_Copy" Fill="RoyalBlue" Stroke="{x:Null}" Margin="-0.012,0,0.001,-9.67" VerticalAlignment="Bottom" Height="3.344"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="0" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Border RenderTransformOrigin="0.492,1.006" Margin="1.081,0,1.086,-8.056" x:Name="border" VerticalAlignment="Bottom" Height="8.622" Background="RoyalBlue" CornerRadius="1,1,0,0"> <Border.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="0" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Border.RenderTransform> </Border> <Border Height="4.994" Background="RoyalBlue" CornerRadius="1,1,0,0" RenderTransformOrigin="0.496,1.001" Margin="0.705,0,0.714,-8.058" x:Name="border1" VerticalAlignment="Bottom"> <Border.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <RotateTransform Angle="0" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Border.RenderTransform> </Border> </Grid> </Viewbox> <Label Name="lbTip" Content="載入中...." FontWeight="Bold" FontSize="15" BorderThickness="0" BorderBrush="{x:Null}" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Background="{x:Null}" Foreground="RoyalBlue" Opacity="0.5"></Label> </Grid> </Window>
後臺CS程式碼如下
using System.Windows.Shapes; namespace LovelyWpf.BaseView { /// <summary> /// LoadingDialog.xaml 的互動邏輯 /// </summary> public partial class LoadingDialog : Window { public LoadingDialog() { InitializeComponent(); } /// <summary> /// 設定提示文字 /// </summary> public void SetTipText(string msg) { this.lbTip.Content = msg; } } }
- 新增View層基類 BaseWindow 和 BaseUserControl,其中BaseWindow是窗體基類,BaseUserControl為控制元件基類。其中在兩者的建構函式中,我們為註冊了View的Loaded事件,並在IDisposable的實現方法Dispose()方法中反註冊了此事件。在Loaded方法中,我們判斷此View的DataContext是否繼承自BaseViewModel,如果是,我們便實現了BaseViewModel的兩個委託。具體實現請檢視程式碼。
BaseWindow 定義如下,繼承自Window類,實現了IDisposable介面。
public class BaseWindow : Window, IDisposable { private LoadingDialog m_loadingTipDialog; public BaseWindow() { this.Loaded += BaseWindow_Loaded; } private void BaseWindow_Loaded(object sender, RoutedEventArgs e) { if (this.DataContext is BaseViewModel) { BaseViewModel vm = this.DataContext as BaseViewModel; vm.ShowLodingEvent = BaseShowLoading; vm.CloseLoadingEvent = BaseCloseLoading; } } private void BaseCloseLoading() { this.IsEnabled = true; if (m_loadingTipDialog != null) { m_loadingTipDialog.Close(); m_loadingTipDialog = null; } } private void BaseShowLoading(string msg) { BaseShowLoading(msg, WindowStartupLocation.CenterOwner); } private void BaseShowLoading(string msg, WindowStartupLocation location) { if (m_loadingTipDialog == null) m_loadingTipDialog = new LoadingDialog(); //設定當前控制元件不可再被點選 this.IsEnabled = false; //設定Loading視窗在底部導航欄不顯示小窗體 m_loadingTipDialog.ShowInTaskbar = false; //獲取Window物件 var win = Window.GetWindow(this); //m_loadingTipDialog.Width = win.ActualWidth; //m_loadingTipDialog.Height = win.ActualHeight; switch (location) { case WindowStartupLocation.CenterOwner://窗體在window的正中央顯示 m_loadingTipDialog.WindowStartupLocation = WindowStartupLocation.CenterOwner; m_loadingTipDialog.Owner = win; m_loadingTipDialog.SetTipText(msg); break; } m_loadingTipDialog.Show(); } public void Dispose() { this.Loaded -= BaseWindow_Loaded; } }
BaseUserControl 定義如下,繼承自UserControl類,也實現了IDisposable介面。
public class BaseUserControl : UserControl, IDisposable { public BaseUserControl() { FindViewModel(); this.Loaded += BaseUserControl_Loaded; } private void BaseUserControl_Loaded(object sender, System.Windows.RoutedEventArgs e) { if (this.DataContext is BaseViewModel) { BaseViewModel vm = this.DataContext as BaseViewModel; vm.ShowLodingEvent = BaseShowLoading; vm.CloseLoadingEvent = BaseCloseLoading; } } #region 進度條 private LoadingDialog m_loadingTipDialog; private void BaseShowLoading(string msg) { BaseShowLoading(msg, WindowStartupLocation.CenterOwner); } private void BaseShowLoading(string msg, WindowStartupLocation location) { if (m_loadingTipDialog == null) m_loadingTipDialog = new LoadingDialog(); //設定當前控制元件不可再被點選 this.IsEnabled = false; //設定Loading視窗在底部導航欄不顯示小窗體 m_loadingTipDialog.ShowInTaskbar = false; //獲取Window物件 var win = Window.GetWindow(this); //m_loadingTipDialog.Width = win.ActualWidth; //m_loadingTipDialog.Height = win.ActualHeight; switch (location) { case WindowStartupLocation.CenterOwner://窗體在window的正中央顯示 m_loadingTipDialog.WindowStartupLocation = WindowStartupLocation.CenterOwner; m_loadingTipDialog.Owner = win; m_loadingTipDialog.SetTipText(msg); break; } m_loadingTipDialog.Show(); } private void BaseCloseLoading() { this.IsEnabled = true; if (m_loadingTipDialog != null) { m_loadingTipDialog.Close(); m_loadingTipDialog = null; } } #endregion public void Dispose() { this.Loaded -= BaseUserControl_Loaded; if (m_loadingTipDialog != null) { m_loadingTipDialog.Close(); m_loadingTipDialog = null; } } public void FindViewModel() { object obj = Caliburn.Micro.ViewModelLocator.LocateForView(this); if (obj != null) { Caliburn.Micro.ViewModelBinder.Bind(obj, this, null); } } /// <summary> /// 用於介面重新整理,待續。。 /// </summary> public virtual void ReloadData() { } }
- 使用教程
View層程式碼
<Button cm:Message.Attach="LoadingData()">顯示進度條</Button>
ViewMdeol層程式碼
public async void LoadingData() { ShowLodingEvent("載入中....."); string str = await Task.Run<string>(() => { Thread.Sleep(5000); return "Hello World"; }); CloseLoadingEvent(); Msg = str; }
顯示效果如下: