WPF进度条样式很方块?

17

我在我的应用程序中使用了一个不确定的进度条,但是我得到了一系列水平运行的方块的不良动画。是否有更好的样式可用,例如vista或windows 7?

我在应用程序中使用不确定进度条,但是出现了一系列水平运行的方块的动画效果不佳。有没有类似于vista或者windows 7的更好的样式可供选择?
5个回答

20

您的进度条样式与当前 Windows 主题相对应。如果在 Windows 7 上运行应用程序并启用 Aero 主题,则进度条将相应地显示。

如果您希望进度条始终保持相同的外观(无论选择了哪个 Windows 主题),则需要为进度条定义自己的样式。

这是 Aero 正常颜色主题的样式:

<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文件中,您的进度条将始终具有此样式。


我有一个问题。当我应用主题并设置 IsIndeterminate = true 时,不定动画在 xaml 编辑器中工作,但在主应用程序中不起作用。这可能是什么原因? - Aks
很难说......如果不使用这种风格,它在两种情况下都能工作吗? - Pavlo Glazkov
1
@Aks:请查看此处关于不确定动画的内容(http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/38a76137-2874-48ed-b7c2-53586e47274a/)。 - Ivan Danilov
我按照你说的做了,可能因为我是个新手,所以没有生效。这是我做的:添加名为“Themes”的新文件夹,在其中添加一个名为“Generic.xaml”的空文件,并将你的代码复制到“Generic.xaml”中。但还是不起作用。请问我漏掉了哪些步骤?谢谢。 - Syaiful Nizam Yahya

12

这是另一个...非常简单的扁平化进度条,用于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>

非常感谢您提供的示例,它对我帮助很大。 - Luke
谢谢,这已经满足了我95%的需求。它只是不能处理垂直滚动条。缺失的部分可以参考这个答案(https://dev59.com/M1bTa4cB1Zd3GeqP-GPD#6849237)。 - Robert Gowland
这对于快速简单的ProgressBar样式非常有效!提醒其他人,如果您想应用自己的画笔,请添加一个FillPART_Track,编辑IndicatorFill和编辑PART_GlowRectBackground - Alexis Leclerc

5

这是我根据Suneet的示例制作的自定义进度条,但在.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值来来回移动它,但在我的情况下是可行的,因为我的进度条是固定宽度的。
如果你有更好的想法,请随意更改storyboard部分。这个页面对我帮助很大。

3
这里有另一个支持普通模式和中间模式的内容:
<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>

0
我找到的最简单的方法是基于https://dev59.com/U2cs5IYBdhLWcg3waTRD#19737148,但更加简化了。
这将产生一个简单的平面外观:
<ProgressBar>
    <ProgressBar.Template>
        <ControlTemplate TargetType="ProgressBar">
            <Border
                BorderBrush="Black"
                BorderThickness="1"
                Background="LightGray"
                >

                <Grid x:Name="PART_Track">
                    <Rectangle
                        x:Name="PART_Indicator"
                        HorizontalAlignment="Left"
                        Fill="Blue"
                        />
                </Grid>
            </Border>
        </ControlTemplate>
    </ProgressBar.Template>
</ProgressBar>

“诀窍”就是只用非常简单的替代品最小化地替换命名部分。虽然这是一个观点问题,但你不一定需要复杂的渐变等来改善默认外观。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接