Тема ProgressBar с декоратором диагональных линий

Я хочу украсить WPF ProgressBar, как показано ниже:

Current

ProgressBar without decoration

Украшенные

ProgressBar with decoration

Кроме того, эти пустые диагональные строки должны перемещаться в анимации выделения слева направо. На данный момент у меня есть этот простой стиль для текущего вида:

<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ProgressBar}">
                <Border x:Name="BorderBackground" CornerRadius="3" BorderThickness="1" BorderBrush="{StaticResource ProgressBarBorderBrush}" Background="{StaticResource ProgressBarBackgroundBrush}">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Determinate" />
                                <VisualState x:Name="Indeterminate" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border x:Name="PART_Track" Margin="2" BorderThickness="1" CornerRadius="2" />
                        <Border x:Name="PART_Indicator" Margin="2" BorderThickness="1" CornerRadius="2" HorizontalAlignment="Left" Background="{StaticResource ProgressBarTrackBackgroundBrush}"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Кто-нибудь может мне помочь? Я искал его, но, возможно, я пропустил правильные ключевые слова, чтобы найти что-то вроде этого, по крайней мере, я обычно вижу (например, в OS X progressbar), что обычно используется это "украшение".

Заранее спасибо;).


Шаблон решения с измененным кодом ответа:

<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ProgressBar}">
                <Border x:Name="BorderBackground" CornerRadius="3" BorderThickness="1" BorderBrush="{StaticResource ProgressBarBorderBrush}" Background="{StaticResource ProgressBarBackgroundBrush}" Effect="{StaticResource LightStrongDownLinearShadowEffect}">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Determinate" />
                                <VisualState x:Name="Indeterminate" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border x:Name="PART_Track" Margin="2" BorderThickness="1" CornerRadius="2" />
                        <Border x:Name="PART_Indicator" Margin="2" BorderThickness="1" CornerRadius="2" HorizontalAlignment="Left" Background="{StaticResource ProgressBarTrackBackgroundBrush}" ClipToBounds="True">
                            <Border x:Name="DiagonalDecorator" Width="5000">
                                <Border.Background>
                                    <DrawingBrush TileMode="Tile" Stretch="None" Viewbox="0,0,1,1" Viewport="0,0,25,25" ViewportUnits="Absolute">
                                        <DrawingBrush.RelativeTransform>
                                            <TranslateTransform X="0" Y="0" />
                                        </DrawingBrush.RelativeTransform>
                                        <DrawingBrush.Drawing>
                                            <GeometryDrawing Brush="#20FFFFFF" Geometry="M10,0 22,0 12,25 0,22 Z" />
                                        </DrawingBrush.Drawing>
                                    </DrawingBrush>
                                </Border.Background>
                                <Border.Triggers>
                                    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                                        <BeginStoryboard>
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetProperty="(Border.Background).(DrawingBrush.RelativeTransform).(TranslateTransform.X)" From="0" To=".25" RepeatBehavior="Forever" Duration="0:0:15" />
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </EventTrigger>
                                </Border.Triggers>
                            </Border>
                        </Border>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Ответ 1

Edit:

В этой статье из codeproject.com есть рабочая версия индикатора прогресса "barber pole" . Найдите статью для "CandyCaneProgressPainter" .

Предыдущий ответ:

Это делает практически то, что вы хотите. Все, что вам нужно сделать, чтобы сделать это, вы хотите ограничить видимость прямоугольника до необходимого процента и изменить отношение высоты/ширины.

Ключевыми словами, которые вы хотите, являются "раскадровка", "анимация" и "триггер"

Вот xaml из ссылки с некоторыми комментариями по ссылке, что делает анимацию гладкой:

 <Rectangle x:Name="pole" Width="100" Height="20" Stroke="Black" StrokeThickness="1">
  <Rectangle.Fill>
   <DrawingBrush TileMode="Tile" Stretch="None" Viewbox="0,0,1,1" Viewport="0,0,25,25" ViewportUnits="Absolute">
    <DrawingBrush.RelativeTransform>
     <TranslateTransform X="0" Y="0" />
    </DrawingBrush.RelativeTransform>
    <DrawingBrush.Drawing>
     <GeometryDrawing Brush="Red" Geometry="M10,0 25,0 15,25 0,25 Z" />    </DrawingBrush.Drawing>
   </DrawingBrush>
  </Rectangle.Fill>
  <Rectangle.Triggers>
   <EventTrigger RoutedEvent="FrameworkElement.Loaded">
    <BeginStoryboard>
     <Storyboard>
      <DoubleAnimation Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.RelativeTransform).(TranslateTransform.X)" From="0" To=".25" RepeatBehavior="Forever" Duration="0:0:1" />
     </Storyboard>
    </BeginStoryboard>
   </EventTrigger>
  </Rectangle.Triggers>
 </Rectangle>

Я думаю, что подергивание происходит, если вы удалите значение ширины, но если значение будет возвращено, оно будет плавным. Weird.

Yup, действительно, в основном потребовалось несколько корректировок с кратным числа правил, ширина в этом случае анимация может быть .1 или .05, если, например, у вас ширина 5000. Теперь она работает здорово!

Ответ 2

В вашей границе PART_Indicator встройте составной путь фигур, чтобы сделать диагональные линии. Вам нужно будет подделать эффект Marquee для получения прокручиваемых диагональных линий, если вы не хотите использовать плагин jquery или другую альтернативу.

Однако то, что вы МОЖЕТЕ сделать в чистом xaml, - создать диагональные линии, сделать много и много из них, чтобы сделать ряд строк диагноза очень длинным. Поскольку они встроены в границу индикатора, они видны только внутри него.

Теперь создайте новую анимацию раскадровки и используйте ControlStoryboardAction Behavior, чтобы вызвать ее загрузку и настроить ее на повторение. Возьмите составной путь по диагональным линиям, выберите ключевой кадр на временной шкале, исходящий из рамы начала, затем перетащите составной путь диагональных линий в одну сторону или установите большую маржу слева, чтобы во время последовательности анимации она перемещалась вправо, Идея - это визуальная мистификация. Ваши диагональные линии будут действовать как анимационная раскадровка, которая только имитирует анимацию шатра. Таким образом, эти строки все равно будут перемещаться по панели, и, надеюсь, их достаточно, чтобы анимация не повторялась до загрузки содержимого. Надеюсь, это имеет смысл ха-ха. Это требует некоторой настройки, но вы можете привести к достойному решению. Удачи!

Ответ 3

Этот пост довольно старый, но я столкнулся с той же проблемой и получил хорошее решение, которое хотел бы поделиться:

  <SolidColorBrush x:Key="ProgressBarBackgroundBrush" Color="Gray" />
  <SolidColorBrush x:Key="ProgressBarTrackBackgroundBrush" Color="#105295" />
  <Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ProgressBar}">
                        <controls:RoundBorder x:Name="BorderBackground" CornerRadius="3" BorderThickness="0"
                        BorderBrush="{StaticResource ProgressBarBorderBrush}"
                        Background="{StaticResource ProgressBarBackgroundBrush}">
                            <Grid>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Determinate" />
                                        <VisualState x:Name="Indeterminate" />
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <Border x:Name="PART_Track" Margin="0" BorderThickness="0" CornerRadius="3"  />
                                <Border x:Name="PART_Indicator" Margin="0" BorderThickness="0" CornerRadius="3" HorizontalAlignment="Left"
                                Background="{StaticResource ProgressBarTrackBackgroundBrush}" ClipToBounds="True">
                                    <Border x:Name="DiagonalDecorator" Width="5000">
                                        <Border.Background>
                                            <DrawingBrush  TileMode="Tile" Stretch="None" Viewbox="0,0,1,1" Viewport="0,0,36,34"  ViewportUnits="Absolute">
                                                <DrawingBrush.RelativeTransform>
                                                    <TranslateTransform X="0" Y="0" />
                                                </DrawingBrush.RelativeTransform>
                                                <DrawingBrush.Drawing>
                                                    <GeometryDrawing Brush="#156dc7" Geometry="M0,0 18,0 36,34 18,34 Z" />
                                                </DrawingBrush.Drawing>
                                            </DrawingBrush>
                                        </Border.Background>
                                        <Border.Triggers>
                                            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                                                <BeginStoryboard>
                                                    <Storyboard>
                                                        <DoubleAnimation Storyboard.TargetProperty="(Border.Background).(DrawingBrush.RelativeTransform).(TranslateTransform.X)"
                                                    From="0" To=".36" RepeatBehavior="Forever" Duration="0:0:18" />
                                                    </Storyboard>
                                                </BeginStoryboard>
                                            </EventTrigger>
                                        </Border.Triggers>
                                    </Border>
                                </Border>
                            </Grid>
                        </controls:RoundBorder >
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>