Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vertical progress bar template .net

I try to customize a .Net vertical progress bar (using Visual 2010), with the following code:

<ProgressBar Name="VolumeMeter" Orientation="Vertical" Margin="4,30,0,0" Value="50" HorizontalAlignment="Left" VerticalAlignment="Top" Height="300" Width="10">
        <ProgressBar.Template>
            <ControlTemplate TargetType="ProgressBar">
                <Border BorderBrush="Green" BorderThickness="1">
                    <Grid Name="PART_Track" Background="Red">
                        <Rectangle Name="PART_Indicator" Fill="Blue"/>                            
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="Orientation" Value="Horizontal">
                        <Setter TargetName="PART_Indicator" Property="VerticalAlignment" Value="Stretch"/>
                        <Setter TargetName="PART_Indicator" Property="HorizontalAlignment" Value="Left"/>
                    </Trigger>
                    <Trigger Property="Orientation" Value="Vertical">
                        <Setter TargetName="PART_Indicator" Property="VerticalAlignment" Value="Bottom"/>
                        <Setter TargetName="PART_Indicator" Property="HorizontalAlignment" Value="Stretch"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </ProgressBar.Template>
    </ProgressBar>

But, it doesn´t show the progress, What's wrong?

like image 201
Peña Avatar asked Apr 19 '11 23:04

Peña


2 Answers

The problem you might be running into is the result of a breaking change in .Net 4.0 that is a result of attempts to improve the performance of the WPF ProgressBar control. (Something that, admittedly, it needed badly.) Refer to http://connect.microsoft.com/VisualStudio/feedback/details/571674/issue-with-vertical-progress-bar-on-4-0-framework

Short version: In .Net 3.5 and earlier, you could author the progress bar and it was smart enough to adjust for vertical or horizontal orientation on its own. In .Net 4.0, you must author your progress bar as though it was horizontal, then use a trigger and transform to rotate it into a vertical orientation when the orientation is vertical. If you're using .Net 4.0 (which I suspect you are), this is why it's impossible for you to get your progress bar to behave the way you expect.

Sadly, this is very poorly documented in MSDN. It's notable that the example at http://msdn.microsoft.com/en-us/library/ms750638.aspx does not mention this, or address it in any way. Likewise, the ProgressBar documentation itself (http://msdn.microsoft.com/en-us/library/system.windows.controls.progressbar.aspx) does not document this breaking change from the prior versions of the presentation foundation. Thank goodness for the bug that was submitted, or I (too) would have thought I'd gone crazy.

The correct way to do this is now something like the following:

<ControlTemplate TargetType="ProgressBar">

  <Border x:Name="Root">
    <!-- Visual tree goes here, be sure to include PART_Indicator and PART_Track -->
  </Border>

  <!-- Triggers must come after the Visual Tree so we can reference names. -->
  <ControlTemplate.Triggers>
    <Trigger Property="Orientation" Value="Vertical">

      <!-- Rotate the progressbar so the left edge is the bottom edge -->
      <Setter TargetName="Root" Property="LayoutTransform">
        <Setter.Value>
          <RotateTransform Angle="270" />
        </Setter.Value>
      </Setter>

      <!-- 
      Fix the render dimensions b/c what was the width is now height and vice-versa. 
      Note that we have to use {RelativeSource TemplatedParent} b/c {TemplateBinding}
      can't be used in a setter's value.
      -->
      <Setter TargetName="Root" Property="Width"
       Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}"
       />
      <Setter TargetName="Root" Property="Height"
       Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"
       />
    </Trigger>
  </ControlTemplate.Triggers>
</ControlTemplate>
like image 106
Greg D Avatar answered Sep 24 '22 01:09

Greg D


from your xaml, it looks like you are not binding it to anything. you have to have something that tells it to update the progress, normally you would bind it to something on your datamodel, or have some method in your codebehind that does it.

like image 30
Muad'Dib Avatar answered Sep 26 '22 01:09

Muad'Dib