Стиль прогрессивного WPF

Я использую неопределенный прогресс в моем приложении, и я получаю эту плохую анимацию из серии блоков, работающих по горизонтали. Разве нет лучшего стиля, такого как vista или windows 7?

Ответы

Ответ 1

В вашей строке выполнения есть стиль, соответствующий текущей теме Windows. Если вы запустите приложение в Windows 7 с темой Aero, ваш индикатор выполнения будет выглядеть соответствующим образом.

Если вы хотите, чтобы он всегда выглядел одинаково (независимо от того, какая тема для Windows выбрана), вам нужно будет определить свой собственный стиль для панели выполнения.

Вот стиль из темы Aero Normal Color:

<LinearGradientBrush x:Key="ProgressBarBorderBrush"
                     EndPoint="0,1"
                     StartPoint="0,0">
    <LinearGradientBrush.GradientStops>
        <GradientStop Color="#B2B2B2"
                      Offset="0"/>
        <GradientStop Color="#8C8C8C"
                      Offset="1"/>
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarBackground"
                     EndPoint="1,0"
                     StartPoint="0,0">
    <LinearGradientBrush.GradientStops>
        <GradientStop Color="#BABABA"
                      Offset="0"/>
        <GradientStop Color="#C7C7C7"
                      Offset="0.5"/>
        <GradientStop Color="#BABABA"
                      Offset="1"/>
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarTopHighlight"
                     StartPoint="0,0"
                     EndPoint="0,1">
    <LinearGradientBrush.GradientStops>
        <GradientStop Color="#80FFFFFF"
                      Offset="0.05"/>
        <GradientStop Color="#00FFFFFF"
                      Offset="0.25"/>
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarGlassyHighlight"
                     StartPoint="0,0"
                     EndPoint="0,1">
    <LinearGradientBrush.GradientStops>
        <GradientStop Color="#50FFFFFF"
                      Offset="0.5385"/>
        <GradientStop Color="#00FFFFFF"
                      Offset="0.5385"/>
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorGlassyHighlight"
                     StartPoint="0,0"
                     EndPoint="0,1">
    <LinearGradientBrush.GradientStops>
        <GradientStop Color="#90FFFFFF"
                      Offset="0.5385"/>
        <GradientStop Color="#00FFFFFF"
                      Offset="0.5385"/>
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<RadialGradientBrush x:Key="ProgressBarIndicatorLightingEffectLeft"
                     RadiusX="1"
                     RadiusY="1"
                     RelativeTransform="1,0,0,1,0.5,0.5">
    <RadialGradientBrush.GradientStops>
        <GradientStop Color="#60FFFFC4"
                      Offset="0"/>
        <GradientStop Color="#00FFFFC4"
                      Offset="1"/>
    </RadialGradientBrush.GradientStops>
</RadialGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorLightingEffect"
                     StartPoint="0,1"
                     EndPoint="0,0">
    <LinearGradientBrush.GradientStops>
        <GradientStop Color="#60FFFFC4"
                      Offset="0"/>
        <GradientStop Color="#00FFFFC4"
                      Offset="1"/>
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<RadialGradientBrush x:Key="ProgressBarIndicatorLightingEffectRight"
                     RadiusX="1"
                     RadiusY="1"
                     RelativeTransform="1,0,0,1,-0.5,0.5">
    <RadialGradientBrush.GradientStops>
        <GradientStop Color="#60FFFFC4"
                      Offset="0"/>
        <GradientStop Color="#00FFFFC4"
                      Offset="1"/>
    </RadialGradientBrush.GradientStops>
</RadialGradientBrush>

<LinearGradientBrush x:Key="ProgressBarIndicatorDarkEdgeLeft"
                     StartPoint="0,0"
                     EndPoint="1,0">
    <LinearGradientBrush.GradientStops>
        <GradientStop Color="#0C000000"
                      Offset="0"/>
        <GradientStop Color="#20000000"
                      Offset="0.3"/>
        <GradientStop Color="#00000000"
                      Offset="1"/>
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorDarkEdgeRight"
                     StartPoint="0,0"
                     EndPoint="1,0">
    <LinearGradientBrush.GradientStops>
        <GradientStop Color="#00000000"
                      Offset="0"/>
        <GradientStop Color="#20000000"
                      Offset="0.7"/>
        <GradientStop Color="#0C000000"
                      Offset="1"/>
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>

<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill" 
                     StartPoint="0,0"
                     EndPoint="1,0">
    <LinearGradientBrush.GradientStops>
        <GradientStop Color="#00FFFFFF"
                      Offset="0"/>
        <GradientStop Color="#60FFFFFF"
                      Offset="0.4"/>
        <GradientStop Color="#60FFFFFF"
                      Offset="0.6"/>
        <GradientStop Color="#00FFFFFF"
                      Offset="1"/>
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>

<Style x:Key="{x:Type ProgressBar}"
       TargetType="{x:Type ProgressBar}">
    <Setter Property="Foreground"
            Value="#01D328"/>
    <Setter Property="Background"
            Value="{StaticResource ProgressBarBackground}"/>
    <Setter Property="BorderBrush"
            Value="{StaticResource ProgressBarBorderBrush}"/>
    <Setter Property="BorderThickness"
            Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ProgressBar}">
                <Grid Name="TemplateRoot"
                      SnapsToDevicePixels="true">
                    <Rectangle Fill="{TemplateBinding Background}"
                               RadiusX="2"
                               RadiusY="2"/>
                    <Border Background="{StaticResource ProgressBarGlassyHighlight}"
                            Margin="1"
                            CornerRadius="2"/>
                    <Border BorderBrush="#80FFFFFF"
                            Background="{StaticResource ProgressBarTopHighlight}"
                            BorderThickness="1,0,1,1"
                            Margin="1"/>
                    <Rectangle Name="PART_Track"
                               Margin="1"/>

                    <Decorator x:Name="PART_Indicator"
                               HorizontalAlignment="Left"
                               Margin="1">
                        <Grid Name="Foreground">
                            <Rectangle x:Name="Indicator"
                                       Fill="{TemplateBinding Foreground}"/>
                            <Grid x:Name="Animation" ClipToBounds="true">
                                <Rectangle x:Name="PART_GlowRect" Width="100" 
                                            Fill="{StaticResource ProgressBarIndicatorAnimatedFill}"
                                            Margin="-100,0,0,0"
                                            HorizontalAlignment="Left">
                                </Rectangle>
                            </Grid>
                            <Grid x:Name="Overlay">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition MaxWidth="15"/>
                                    <ColumnDefinition Width="0.1*"/>
                                    <ColumnDefinition MaxWidth="15"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition />
                                    <RowDefinition />
                                </Grid.RowDefinitions>
                                <Rectangle x:Name="LeftDark"
                                           Grid.RowSpan="2"
                                           Fill="{StaticResource ProgressBarIndicatorDarkEdgeLeft}"
                                           RadiusX="1"
                                           RadiusY="1"
                                           Margin="1,1,0,1"/>
                                <Rectangle x:Name="RightDark"
                                           Grid.RowSpan="2"
                                           Grid.Column="2"
                                           RadiusX="1"
                                           RadiusY="1"
                                           Fill="{StaticResource ProgressBarIndicatorDarkEdgeRight}"
                                           Margin="0,1,1,1"/>
                                <Rectangle x:Name="LeftLight"
                                           Grid.Column="0"
                                           Grid.Row="2"
                                           Fill="{StaticResource ProgressBarIndicatorLightingEffectLeft}"/>
                                <Rectangle x:Name="CenterLight"
                                           Grid.Column="1"
                                           Grid.Row="2"
                                           Fill="{StaticResource ProgressBarIndicatorLightingEffect}"/>
                                <Rectangle x:Name="RightLight"
                                           Grid.Column="2"
                                           Grid.Row="2"
                                           Fill="{StaticResource ProgressBarIndicatorLightingEffectRight}"/>
                                <Border x:Name="Highlight1"
                                        Grid.RowSpan="2"
                                        Grid.ColumnSpan="3"
                                        Background="{StaticResource ProgressBarIndicatorGlassyHighlight}"/>
                                <Border x:Name="Highlight2"
                                        Grid.RowSpan="2" 
                                        Grid.ColumnSpan="3"
                                        Background="{StaticResource ProgressBarTopHighlight}"/>
                            </Grid>
                        </Grid>
                    </Decorator>

                    <Border BorderThickness="{TemplateBinding BorderThickness}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            CornerRadius="2"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="Orientation"
                             Value="Vertical">
                        <Setter TargetName="TemplateRoot"
                                Property="LayoutTransform">
                            <Setter.Value>
                                <RotateTransform Angle="-90"/>
                            </Setter.Value>
                        </Setter>
                    </Trigger>

                    <Trigger Property="IsIndeterminate"
                             Value="true">
                        <Setter TargetName="LeftDark"
                                Property="Visibility"
                                Value="Collapsed"/>
                        <Setter TargetName="RightDark"
                                Property="Visibility"
                                Value="Collapsed"/>
                        <Setter TargetName="LeftLight"
                                Property="Visibility"
                                Value="Collapsed"/>
                        <Setter TargetName="CenterLight"
                                Property="Visibility"
                                Value="Collapsed"/>
                        <Setter TargetName="RightLight"
                                Property="Visibility"
                                Value="Collapsed"/>
                        <Setter TargetName="Indicator"
                                Property="Visibility"
                                Value="Collapsed"/>
                    </Trigger>
                    <Trigger Property="IsIndeterminate"
                             Value="false">
                        <Setter TargetName="Animation"
                                Property="Background"
                                Value="#80B5FFA9"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Поместите этот код в файл Themes/Generic.xaml в ваше приложение, и ваши индикаторы выполнения всегда будут иметь этот стиль.

Ответ 2

Это еще один... очень простой плавный индикатор выполнения для режима IsInderminate -

    <ControlTemplate x:Key="CustomProgressBar" TargetType="ProgressBar" >
        <Grid Name="TemplateRoot" SnapsToDevicePixels="True">
            <Rectangle RadiusX="2" RadiusY="2" Fill="Transparent" />
            <Border CornerRadius="0,0,0,0" Margin="1,1,1,1">
                <Border.Background>
                    <SolidColorBrush Color="Transparent"/>                       
                </Border.Background>
            </Border>
            <Border BorderThickness="0,0,0,0" BorderBrush="Transparent" Margin="1,1,1,1">
                <Border.Background>
                    <SolidColorBrush Color="Transparent"/>                        
                </Border.Background>
            </Border>
            <Rectangle Name="PART_Track" Margin="1,1,1,1" />
            <Decorator Name="PART_Indicator" Margin="1,1,1,1" HorizontalAlignment="Left">
                <Grid Name="Foreground">
                    <Rectangle Fill="Transparent" Name="Indicator" />
                    <Grid Name="Animation" ClipToBounds="True">
                        <Border Name="PART_GlowRect" Width="100"  Margin="0,0,0,0" HorizontalAlignment="Left" Background="LightBlue"/>                                                            
                    </Grid>
                    <Grid Name="Overlay">                         
                    </Grid>
                </Grid>
            </Decorator>
            <Border BorderThickness="0" CornerRadius="0,0,0,0" BorderBrush="Transparent" />
        </Grid>           
    </ControlTemplate>

Ответ 3

Это настраиваемый индикатор выполнения, который я сделал из примера Suneet, но с анимацией IsIndeterminate, работающей в .NET 3.5:

<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
    <Setter Property="Foreground" Value="#54bdcd"/>
    <Setter Property="Background" Value="#000000"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ProgressBar}">
                <Grid Name="TemplateRoot" SnapsToDevicePixels="true">
                    <Rectangle Fill="{TemplateBinding Background}"/>
                    <Rectangle Name="PART_Track" Margin="0"/>
                    <Decorator x:Name="PART_Indicator" HorizontalAlignment="Left" Margin="0">
                        <Grid Name="Foreground">
                            <Rectangle Fill="{TemplateBinding Foreground}" Name="Indicator" />
                            <Grid Name="Animation" ClipToBounds="True">
                                <Border Name="PART_GlowRect"  Margin="0,0,0,0" HorizontalAlignment="Left" Background="{TemplateBinding Foreground}"/>
                            </Grid>
                            <Grid Name="Overlay">
                            </Grid>
                        </Grid>
                    </Decorator>

                    <Border BorderThickness="{TemplateBinding BorderThickness}"
                        BorderBrush="{TemplateBinding BorderBrush}"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsIndeterminate" Value="true">
                        <Setter TargetName="Indicator" Property="Fill" Value="Transparent" />
                        <Setter TargetName="PART_GlowRect" Property="Width" Value="100" />
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ThicknessAnimation 
                                        Storyboard.TargetName="PART_GlowRect"
                                        Storyboard.TargetProperty="Margin"
                                        From="-50,0,0,0"  To="400,0,0,0" Duration="0:0:2"
                                        AutoReverse="True" RepeatBehavior="Forever" />
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Это своего рода хак, потому что я перемещаю неопределенный бар вперед и назад, изменяя его значение marginleft, но в моем случае это было доступно, потому что мой индикатор выполнения был фиксированной шириной.

Если у вас есть идея лучше, не стесняйтесь менять часть раскадровки. Эта страница мне очень помогла.

Ответ 4

Вот еще один, поддерживающий обычный и промежуточный режим:

<Style TargetType="{x:Type ProgressBar}">
    <Setter Property="Foreground" Value="#1BA1E2"/>
    <Setter Property="Background" Value="#EEEEEE"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ProgressBar}">
                <Grid Name="TemplateRoot" SnapsToDevicePixels="true">
                    <Rectangle Fill="{TemplateBinding Background}"/>
                    <Rectangle Name="PART_Track" Margin="0"/>
                    <Decorator x:Name="PART_Indicator" HorizontalAlignment="Left" Margin="0">
                        <Grid Name="Foreground">
                            <Rectangle Fill="{TemplateBinding Foreground}" Name="Indicator" />
                            <Grid x:Name="Animation" ClipToBounds="true" Visibility="Hidden">
                                <Rectangle Fill="{TemplateBinding Background}" Name="HiderPre" Margin="0,0,50,0">
                                    <Rectangle.RenderTransform>
                                        <ScaleTransform x:Name="HiderPreTransform" ScaleX="0"/>
                                    </Rectangle.RenderTransform>
                                </Rectangle>
                                <Rectangle Fill="{TemplateBinding Background}" Name="HiderPost" RenderTransformOrigin="1, 0" Margin="50,0,0,0">
                                    <Rectangle.RenderTransform>
                                        <ScaleTransform x:Name="HiderPostTransform" ScaleX="1"  />
                                    </Rectangle.RenderTransform>
                                </Rectangle>
                            </Grid>
                            <Grid Name="Overlay">
                            </Grid>
                        </Grid>
                    </Decorator>

                    <Border BorderThickness="{TemplateBinding BorderThickness}"
                            BorderBrush="{TemplateBinding BorderBrush}"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsIndeterminate" Value="true">
                        <Setter TargetName="Animation" Property="Visibility" Value="Visible" />

                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard RepeatBehavior="Forever">
                                    <DoubleAnimation
                                        Storyboard.TargetName="HiderPreTransform"
                                        Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
                                        To="1"
                                        Duration="0:00:4" AutoReverse="True"/>
                                    <DoubleAnimation
                                        Storyboard.TargetName="HiderPostTransform"
                                        Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
                                        To="0"
                                        Duration="0:00:4" AutoReverse="True"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="Gray" />
        </Trigger>
    </Style.Triggers>
</Style>