简体   繁体   English

在WPF控件上显示“加载”指示符的最佳方法是什么

[英]What is the best way to display a 'loading' indicator on a WPF control

In C#.Net WPF During UserControl.Load -> 在C#.Net WPF期间UserControl.Load - >

What is the best way of showing a whirling circle / 'Loading' Indicator on the UserControl until it has finished gathering data and rendering it's contents? 在UserControl上显示旋转圆圈/“加载”指示器的最佳方法是什么,直到它完成收集数据并呈现其内容为止?

I generally would create a layout like this: 我通常会创建这样的布局:

<Grid>
    <Grid x:Name="MainContent" IsEnabled="False">
    ...
    </Grid>

    <Grid x:Name="LoadingIndicatorPanel">
    ...
    </Grid>
</Grid>

Then I load the data on a worker thread, and when it's finished I update the UI under the "MainContent" grid and enable the grid, then set the LoadingIndicatorPanel's Visibility to Collapsed. 然后我在工作线程上加载数据,当它完成后,我更新“MainContent”网格下的UI并启用网格,然后将LoadingIndicatorPanel的Visibility设置为Collapsed。

I'm not sure if this is what you were asking or if you wanted to know how to show an animation in the loading label. 我不确定这是你要问的,或者你是否想知道如何在加载标签中显示动画。 If it's the animation you're after, please update your question to be more specific. 如果这是你想要的动画,请更新你的问题以便更具体。

This is something that I was working on just recently in order to create a loading animation. 这是我最近正在努力创建加载动画的东西。 This xaml will produce an animated ring of circles. 这个xaml会产生一个动画圆环。

My initial idea was to create an adorner and use this animation as it's content, then to display the loading animation in the adorners layer and grey out the content underneath. 我最初的想法是创建一个装饰者并使用这个动画作为内容,然后在装饰图层中显示加载动画并使下面的内容变灰。

Haven't had the chance to finish it yet, so I thought I would just post the animation for your reference. 还没有机会完成它,所以我想我会发布动画供你参考。

<Window 
    x:Class="WpfApplication2.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1"
    Height="300"
    Width="300"
    >
    <Window.Resources>
        <Color x:Key="FilledColor" A="255" B="155" R="155" G="155"/>
        <Color x:Key="UnfilledColor" A="0" B="155" R="155" G="155"/>

        <Storyboard x:Key="Animation0" FillBehavior="Stop" BeginTime="00:00:00.0" RepeatBehavior="Forever">
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="_00" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>

        <Storyboard x:Key="Animation1" BeginTime="00:00:00.2" RepeatBehavior="Forever">
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="_01" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>

        <Storyboard x:Key="Animation2" BeginTime="00:00:00.4" RepeatBehavior="Forever">
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="_02" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>

        <Storyboard x:Key="Animation3" BeginTime="00:00:00.6" RepeatBehavior="Forever">
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="_03" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>

        <Storyboard x:Key="Animation4" BeginTime="00:00:00.8" RepeatBehavior="Forever">
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="_04" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>

        <Storyboard x:Key="Animation5" BeginTime="00:00:01.0" RepeatBehavior="Forever">
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="_05" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>

        <Storyboard x:Key="Animation6" BeginTime="00:00:01.2" RepeatBehavior="Forever">
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="_06" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>

        <Storyboard x:Key="Animation7" BeginTime="00:00:01.4" RepeatBehavior="Forever">
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="_07" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>

    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource Animation0}"/>
            <BeginStoryboard Storyboard="{StaticResource Animation1}"/>
            <BeginStoryboard Storyboard="{StaticResource Animation2}"/>
            <BeginStoryboard Storyboard="{StaticResource Animation3}"/>
            <BeginStoryboard Storyboard="{StaticResource Animation4}"/>
            <BeginStoryboard Storyboard="{StaticResource Animation5}"/>
            <BeginStoryboard Storyboard="{StaticResource Animation6}"/>
            <BeginStoryboard Storyboard="{StaticResource Animation7}"/>
        </EventTrigger>
    </Window.Triggers>

    <Canvas>
        <Canvas Canvas.Left="21.75" Canvas.Top="14" Height="81.302" Width="80.197">
            <Canvas.Resources>
                <Style TargetType="Ellipse">
                    <Setter Property="Width" Value="15"/>
                    <Setter Property="Height" Value="15" />
                    <Setter Property="Fill" Value="#FFFFFFFF" />
                </Style>
            </Canvas.Resources>

            <Ellipse x:Name="_00" Canvas.Left="24.75" Canvas.Top="50"/>
            <Ellipse x:Name="_01" Canvas.Top="36" Canvas.Left="29.5"/>
            <Ellipse x:Name="_02" Canvas.Left="43.5" Canvas.Top="29.75"/>
            <Ellipse x:Name="_03" Canvas.Left="57.75" Canvas.Top="35.75"/>
            <Ellipse x:Name="_04" Canvas.Left="63.5" Canvas.Top="49.75" />
            <Ellipse x:Name="_05" Canvas.Left="57.75" Canvas.Top="63.5"/>
            <Ellipse x:Name="_06" Canvas.Left="43.75" Canvas.Top="68.75"/>
            <Ellipse x:Name="_07" Canvas.Top="63.25" Canvas.Left="30" />
            <Ellipse Stroke="{x:Null}" Width="39.5" Height="39.5" Canvas.Left="31.75" Canvas.Top="37" Fill="{x:Null}"/>
        </Canvas>
    </Canvas>
</Window>

I improved on Ian Oakes Design and build an scalable version of his loading indicator: 我对Ian Oakes Design进行了改进,并构建了一个可扩展的加载指示器版本:

<UserControl x:Class="Mesap.Framework.UI.Controls.BusyIndicator"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" Name="Root" Foreground="#9b9b9b"
             d:DesignHeight="100" d:DesignWidth="100">
    <Grid>
        <Grid.Resources>
            <Storyboard x:Key="Animation0" FillBehavior="Stop" BeginTime="00:00:00.0" RepeatBehavior="Forever">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E00" Storyboard.TargetProperty="Opacity">
                    <LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="1"/>
                    <LinearDoubleKeyFrame KeyTime="00:00:01.6" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>

            <Storyboard x:Key="Animation1" BeginTime="00:00:00.2" RepeatBehavior="Forever">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E01" Storyboard.TargetProperty="Opacity">
                    <LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="1"/>
                    <LinearDoubleKeyFrame KeyTime="00:00:01.6" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>

            <Storyboard x:Key="Animation2" BeginTime="00:00:00.4" RepeatBehavior="Forever">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E02" Storyboard.TargetProperty="Opacity">
                    <LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="1"/>
                    <LinearDoubleKeyFrame KeyTime="00:00:01.6" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>

            <Storyboard x:Key="Animation3" BeginTime="00:00:00.6" RepeatBehavior="Forever">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E03" Storyboard.TargetProperty="Opacity">
                    <LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="1"/>
                    <LinearDoubleKeyFrame KeyTime="00:00:01.6" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>

            <Storyboard x:Key="Animation4" BeginTime="00:00:00.8" RepeatBehavior="Forever">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E04" Storyboard.TargetProperty="Opacity">
                    <LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="1"/>
                    <LinearDoubleKeyFrame KeyTime="00:00:01.6" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>

            <Storyboard x:Key="Animation5" BeginTime="00:00:01.0" RepeatBehavior="Forever">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E05" Storyboard.TargetProperty="Opacity">
                    <LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="1"/>
                    <LinearDoubleKeyFrame KeyTime="00:00:01.6" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>

            <Storyboard x:Key="Animation6" BeginTime="00:00:01.2" RepeatBehavior="Forever">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E06" Storyboard.TargetProperty="Opacity">
                    <LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="1"/>
                    <LinearDoubleKeyFrame KeyTime="00:00:01.6" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>

            <Storyboard x:Key="Animation7" BeginTime="00:00:01.4" RepeatBehavior="Forever">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E07" Storyboard.TargetProperty="Opacity">
                    <LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="1"/>
                    <LinearDoubleKeyFrame KeyTime="00:00:01.6" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>

            <Style TargetType="Ellipse">
                <Setter Property="Fill" Value="{Binding ElementName=Root, Path=Foreground}"/>

            </Style>
        </Grid.Resources>
        <Grid.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                <BeginStoryboard Storyboard="{StaticResource Animation0}"/>
                <BeginStoryboard Storyboard="{StaticResource Animation1}"/>
                <BeginStoryboard Storyboard="{StaticResource Animation2}"/>
                <BeginStoryboard Storyboard="{StaticResource Animation3}"/>
                <BeginStoryboard Storyboard="{StaticResource Animation4}"/>
                <BeginStoryboard Storyboard="{StaticResource Animation5}"/>
                <BeginStoryboard Storyboard="{StaticResource Animation6}"/>
                <BeginStoryboard Storyboard="{StaticResource Animation7}"/>
            </EventTrigger>
        </Grid.Triggers>

        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Ellipse x:Name="E00" Grid.Row="4" Grid.Column="0" Grid.RowSpan="3" Grid.ColumnSpan="3" Width="Auto" Height="Auto" Opacity="0"/>
        <Ellipse x:Name="E01" Grid.Row="1" Grid.Column="1" Grid.RowSpan="3" Grid.ColumnSpan="3" Width="Auto" Height="Auto" Opacity="0" />
        <Ellipse x:Name="E02" Grid.Row="0" Grid.Column="4" Grid.RowSpan="3" Grid.ColumnSpan="3" Width="Auto" Height="Auto" Opacity="0" />
        <Ellipse x:Name="E03" Grid.Row="1" Grid.Column="7" Grid.RowSpan="3" Grid.ColumnSpan="3" Width="Auto" Height="Auto" Opacity="0" />
        <Ellipse x:Name="E04" Grid.Row="4" Grid.Column="8" Grid.RowSpan="3" Grid.ColumnSpan="3" Width="Auto" Height="Auto" Opacity="0" />
        <Ellipse x:Name="E05" Grid.Row="7" Grid.Column="7" Grid.RowSpan="3" Grid.ColumnSpan="3" Width="Auto" Height="Auto" Opacity="0" />
        <Ellipse x:Name="E06" Grid.Row="8" Grid.Column="4" Grid.RowSpan="3" Grid.ColumnSpan="3" Width="Auto" Height="Auto" Opacity="0" />
        <Ellipse x:Name="E07" Grid.Row="7" Grid.Column="1" Grid.RowSpan="3" Grid.ColumnSpan="3" Width="Auto" Height="Auto" Opacity="0" />
    </Grid>
</UserControl>

If you are running it on Vista, you could also just use the default wait cursor. 如果您在Vista上运行它,您也可以使用默认的等待光标。

this.Cursor = Cursors.Wait; this.Cursor = Cursors.Wait;

Use BusyIndicator. 使用BusyIndi​​cator。 It's a silverlight thing. 这是一件银色的事情。

You can show animated gif as loading element 您可以将动画gif显示为加载元素

XAML XAML

<WindowsFormsHost>
    <winForms:PictureBox x:Name="pictureBoxLoading" />
</WindowsFormsHost>

CODE BEHIND 代码背后

pictureBoxLoading.Image = System.Drawing.Image.FromFile("images/ajax-loader.gif");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM