虚线进度条

时间:2015-11-30 14:53:03

标签: c# wpf xaml

我想创建一个虚线的进度条,我希望有人可以帮我实现。它应该看起来像下面的草图,但有黑色背景。使用在达到特定百分比时从灰色变为白色的圆圈可视化进度。理想情况下,点的数量应动态调整到条的宽度。

+--------------------------------------------------+
|  O    O    O    O    O    O    O    O    O    O  |
+--------------------------------------------------+

这可以单独使用样式完成,还是必须创建自定义控件?

1 个答案:

答案 0 :(得分:2)

正如Chris W在评论中所说,有几种方法可以通过造型和模板来解决这个问题。这是一个例子:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>
        <Style TargetType="{x:Type ProgressBar}">
            <Style.Resources>
                <Style x:Key="NormalDot" TargetType="{x:Type Ellipse}">
                    <Setter Property="Margin" Value="4" />
                    <Setter Property="Width" Value="10" />
                    <Setter Property="Height" Value="10" />
                    <Setter Property="Fill" Value="Gray" />
                </Style>
                <Style x:Key="ProgressDot" BasedOn="{StaticResource NormalDot}"
                       TargetType="{x:Type Ellipse}">
                    <Setter Property="Fill" Value="White" />
                </Style>
            </Style.Resources>
            <Setter Property="Background" Value="Black" />
            <Setter Property="Height" Value="18" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ProgressBar}">
                        <Grid Background="{TemplateBinding Background}">
                            <StackPanel x:Name="PART_Track" Orientation="Horizontal"
                                HorizontalAlignment="Left" VerticalAlignment="Center">
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                                <Ellipse Style="{StaticResource NormalDot}" />
                            </StackPanel>

                            <StackPanel x:Name="PART_Indicator" Orientation="Horizontal" 
                                HorizontalAlignment="Left" VerticalAlignment="Center">
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                                <Ellipse Style="{StaticResource ProgressDot}" />
                            </StackPanel>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <Grid>
        <ProgressBar Value="{Binding Value, ElementName=_slider}"
            VerticalAlignment="Top" />
        <Slider x:Name="_slider" Minimum="0" Maximum="100"
            VerticalAlignment="Bottom" />
    </Grid>
</Window>

基本思路是两个 StackPanel 容器,每个容器包含十个 Ellipse 元素。第二个 StackPanel 在第一个网格上分层,但其宽度与进度条的当前值一致,然后提供白色“点”的所需效果“随着进步的增加而出现。如果您想要不同数量的点,那么您可以增加或减少 Ellipse 元素的数量:只需记住每个面板中需要相同的数字。

此技术的一种变体将用一对矩形 ItemsControl s, StackPanel Ellipse strong>元素填充自定义 DrawingBrush es。

根据您声明的要求,两种方法的弱点在于:(a)您没有获得任何动画效果;(b)您获得了部分填充的椭圆。您可以通过限制代码中进度条的值来缓解(b),但是要舍入到最近的 x %,然而要解决(a)我认为你正在寻找一个新的控件从现有的 ProgressBar 继承。