2011-12-22 17 views
10

Quiero decorar el WPF ProgressBar como la siguiente imagen:ProgressBar Theme con líneas diagonales decorador

actual:

ProgressBar without decoration

Decoradas:

ProgressBar with decoration

Además, esas líneas diagonales en blanco deben moverse en animación de marquesina de izquierda a derecha. Por el momento tengo este estilo sencillo para la apariencia actual:

<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> 

¿Alguien me puede ayudar a conseguirlo? Lo busqué, pero tal vez me perdí las palabras clave correctas para encontrar algo como esto, al menos usualmente veo (como en la barra de progreso de OS X) que esta "decoración" se usa generalmente.

Gracias de antemano;).


plantilla de solución con el código de respuesta un poco modificado:

<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

Por favor, ten en cuenta que una barra de progreso con animaciones y gradientes podría ser contraproducente productivo; le costará tiempo de CPU cuando ya está esperando algo ... –

+0

Hmmm, no vi ningún problema de rendimiento al probarlo. Si veo algo, lo publico. Gracias por el consejo;) – dbalboa

+0

La barra de progreso de Windows Phone es famosa por consumir demasiada energía: http://www.jeff.wilcox.name/2010/08/performanceprogressbar/ –

Respuesta

4

Editar:

This artículo de codeproject.com tiene una versión de trabajo del "polo del peluquero" barra de progreso. Busque en el artículo "CandyCaneProgressPainter".

respuesta anterior:

This hace casi exactamente lo que quiere. Todo lo que tiene que hacer para que sea lo que quiere es restringir la visibilidad del rectángulo al porcentaje que desea y cambiar la relación alto/ancho.

Las palabras clave que desea son "guión", "animado" y "disparador"

Aquí es el xaml desde el enlace con algunos comentarios desde el enlace en la fabricación de la animación suave:

<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> 

Supongo que las sacudidas se producen si elimina el valor de "ancho", pero si el valor se vuelve a poner, se ejecuta sin problemas. Extraño.

Sí, de hecho, básicamente, se necesitaban algunos ajustes con los múltiplos de las reglas numéricas, el ancho en este caso la animación puede ser .1 o a .05 si, por ejemplo, tiene un ancho de 5000 .... ahora ¡funciona genial!

+0

El artículo del proyecto de código fue genial, pero es para winforms. No importa, es agradable;). Utilicé su primera respuesta para hacer lo que quería, y funciona bastante bien con algunos ajustes. Usó un ancho de 5.000, como dicen, y ajusta la duración para que sea uniforme. También marque la propiedad ClipToBounds = Verdadero del elemento padre. Gracias! PD: Escribiré la plantilla con la solución en el mensaje de pregunta. – dbalboa

+0

Hmmm, pensó que era. Oh, bueno, supongo que lo eliminaré entonces. Por lo que vale, los controles de winforms se pueden hospedar en wpf. – mydogisbox

3

En su frontera PART_Indicator incrustar un trazado compuesto de las formas de hacer las líneas diagonales. Tendrás que falsificar el efecto Marquee para obtener las líneas diagonales desplazables, a menos que quieras usar un plugin jquery u otra alternativa.

Sin embargo, lo que PUEDE hacer en pure xaml es crear las líneas diagonales, hacer muchas y muchas para que la fila de líneas de diagnóstico sea muy larga. Como están incrustados en el borde del indicador, solo son visibles dentro de él.

Ahora cree una nueva animación del guión gráfico y use un ControlStoryboardAction Behavior para activarlo y configurarlo para que se repita. Tome la ruta compuesta de líneas diagonales y elija un fotograma clave en su línea de tiempo a una distancia del cuadro inicial, luego arrastre la ruta compuesta de líneas diagonales hacia un lado o establezca un margen grande hacia la izquierda para que durante la secuencia de animación se desplace hacia la derecha . La idea es que es un engaño visual. Sus líneas diagonales solo actuarán como un guión gráfico de animación que solo imita la animación de marquesina. Entonces esas líneas se moverán a través de la barra y con suerte ya habrá suficientes como para que la animación no se repita antes de que se cargue el contenido. Espero que esto tenga sentido jaja. Requiere algunos ajustes pero puede dar como resultado una solución decente. ¡La mejor de las suertes!

+0

¡Gracias! Finalmente hecho con la respuesta de Mydogisbox, pero tu idea era correcta;) – dbalboa

+0

No te preocupes, siempre y cuando tengas tu respuesta, no me di cuenta de la otra cuando publiqué. ¡Feliz Navidad! :) –

0

Este post es bastante antiguo, pero sólo se enfrentó al mismo problema y consiguió una buena solución me gustaría compartir:

<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>