Search code examples
c#wpfxamltemplatesprogress-bar

How do I make a custom shape of progressbar in wpf?


I would like to customise a progressbar for loading in C# WPF. Instead of a rectangle, it should have some small sharpness at the end, looking something like this: enter image description here

When it has completed loading, the sharpness should disappear.

Currently, this is what I have done.

enter image description here

How can I achieve that customised loading bar?

This is my code, XAML

<Window x:Class="loadingbarSolution.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
    Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style x:Key="{x:Type ProgressBar}"
           TargetType="{x:Type ProgressBar}">
    
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ProgressBar">
                        <Border BorderBrush="#D9DCE1" BorderThickness="0" Background="#FF0C0B0B" CornerRadius="0" Padding="0">
                            <Grid x:Name="PART_Track">
                                <Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left" Fill="#FF2BA9FF" />
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <ProgressBar x:Name="IMSIProgressBar" 
            HorizontalAlignment="Left" 
            Height="20" Margin="82,136,0,0" 
            VerticalAlignment="Top" 
            Width="200" 
            BorderThickness="1" Background="#FF0C0B0B"/>
    </Grid>
</Window>

What should I do?


Solution

  • Back Code:

    class MyCustomConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return new Thickness(0, 0, -(double)value, 0);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    Template:

    <ControlTemplate TargetType="ProgressBar">
        <ControlTemplate.Resources>
            <local:MyCustomConverter x:Key="sttc"/>
        </ControlTemplate.Resources>
        <Border BorderBrush="#D9DCE1" BorderThickness="0" Background="#FF0C0B0B" CornerRadius="0" Padding="0" ClipToBounds="True">
            <Grid x:Name="PART_Track" Margin="{TemplateBinding Height ,Converter={StaticResource sttc}}">
                <Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left" Fill="#FF2BA9FF" RenderTransformOrigin="0,0">
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <SkewTransform AngleX="-45"/>
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
            </Grid>
        </Border>
    </ControlTemplate>
    

    Notice: If the height is fixed, the converter is unnecessary, set margin to a fixed thickness. Converter is just work for auto sizing.