1. 程式人生 > >WPF 簡易耗時載入進度條

WPF 簡易耗時載入進度條

本文實現了簡易的WPF載入進度條,其MVVM框架基於Caliburn.Micro 3.2.0,相關框架的知識請自行百度學習。

  1. 建立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
        }

     

  2. 建立載入進度條彈窗 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;
            }
        }
    }

     

  3. 新增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() { }
            
        }

     

  4. 使用教程
    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;
            }

    顯示效果如下: