Browse Source

Allow customisation of ProgressBar text format.

pull/8454/head
Eric M 4 years ago
parent
commit
435419588a
  1. 27
      samples/ControlCatalog/Pages/ProgressBarPage.xaml
  2. 27
      src/Avalonia.Controls/Converters/StringFormatConverter.cs
  3. 23
      src/Avalonia.Controls/ProgressBar.cs
  4. 21
      src/Avalonia.Themes.Default/Controls/ProgressBar.xaml
  5. 16
      src/Avalonia.Themes.Fluent/Controls/ProgressBar.xaml

27
samples/ControlCatalog/Pages/ProgressBarPage.xaml

@ -1,22 +1,37 @@
<UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ControlCatalog.Pages.ProgressBarPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h2">A progress bar control</TextBlock>
<StackPanel>
<StackPanel Spacing="5">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock VerticalAlignment="Center">Maximum</TextBlock>
<NumericUpDown x:Name="maximum" Value="100" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock VerticalAlignment="Center">Minimum</TextBlock>
<NumericUpDown x:Name="minimum" Value="0" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock VerticalAlignment="Center">Progress Text Format</TextBlock>
<TextBox x:Name="stringFormat" Text="{}{0:0}%" VerticalAlignment="Center"/>
</StackPanel>
<CheckBox x:Name="showProgress" Margin="10,16,0,0" Content="Show Progress Text" />
<CheckBox x:Name="isIndeterminate" Margin="10,16,0,0" Content="Toggle Indeterminate" />
<StackPanel Orientation="Horizontal" Margin="0,16,0,0" HorizontalAlignment="Center" Spacing="16">
<StackPanel Spacing="16">
<ProgressBar IsIndeterminate="{Binding #isIndeterminate.IsChecked}" ShowProgressText="{Binding #showProgress.IsChecked}" Value="{Binding #hprogress.Value}" />
<ProgressBar IsIndeterminate="{Binding #isIndeterminate.IsChecked}" ShowProgressText="{Binding #showProgress.IsChecked}" Value="{Binding #hprogress.Value}"
Minimum="{Binding #minimum.Value}" Maximum="{Binding #maximum.Value}" ProgressTextFormat="{Binding #stringFormat.Text}"/>
</StackPanel>
<ProgressBar IsIndeterminate="{Binding #isIndeterminate.IsChecked}" ShowProgressText="{Binding #showProgress.IsChecked}" Value="{Binding #vprogress.Value}" Orientation="Vertical" />
<ProgressBar IsIndeterminate="{Binding #isIndeterminate.IsChecked}" ShowProgressText="{Binding #showProgress.IsChecked}" Value="{Binding #vprogress.Value}" Orientation="Vertical"
Minimum="{Binding #minimum.Value}" Maximum="{Binding #maximum.Value}" ProgressTextFormat="{Binding #stringFormat.Text}"/>
</StackPanel>
<StackPanel Margin="16">
<Slider Name="hprogress" Maximum="100" Value="40" />
<Slider Name="vprogress" Maximum="100" Value="60" />
<Slider Name="hprogress" Minimum="{Binding #minimum.Value}" Maximum="{Binding #maximum.Value}" Value="40" />
<Slider Name="vprogress" Minimum="{Binding #minimum.Value}" Maximum="{Binding #maximum.Value}" Value="60" />
</StackPanel>
<StackPanel Spacing="10">
<ProgressBar VerticalAlignment="Center" IsIndeterminate="True" />
<ProgressBar VerticalAlignment="Center" IsIndeterminate="True"
Minimum="{Binding #minimum.Value}" Maximum="{Binding #maximum.value}"/>
<ProgressBar VerticalAlignment="Center" Value="5" Maximum="10" />
<ProgressBar VerticalAlignment="Center" Value="50" />
<ProgressBar VerticalAlignment="Center" Value="50" Minimum="25" Maximum="75" />

27
src/Avalonia.Controls/Converters/StringFormatConverter.cs

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Avalonia.Data;
using Avalonia.Data.Converters;
namespace Avalonia.Controls.Converters;
/// <summary>
/// Calls <see cref="string.Format(string, object[])"/> on the passed in values, where the first element in the list
/// is the string, and everything after it is passed into the object array in order.
/// </summary>
public class StringFormatConverter : IMultiValueConverter
{
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
{
try
{
return string.Format((string)values[0]!, values.Skip(1).ToArray());
}
catch (Exception e)
{
return new BindingNotification(e, BindingErrorType.Error);
}
}
}

23
src/Avalonia.Controls/ProgressBar.cs

@ -96,6 +96,7 @@ namespace Avalonia.Controls
}
}
private double _percentage;
private double _indeterminateStartingOffset;
private double _indeterminateEndingOffset;
private Border? _indicator;
@ -106,9 +107,17 @@ namespace Avalonia.Controls
public static readonly StyledProperty<bool> ShowProgressTextProperty =
AvaloniaProperty.Register<ProgressBar, bool>(nameof(ShowProgressText));
public static readonly StyledProperty<string> ProgressTextFormatProperty =
AvaloniaProperty.Register<ProgressBar, string>(nameof(ProgressTextFormat), "{1:0}%");
public static readonly StyledProperty<Orientation> OrientationProperty =
AvaloniaProperty.Register<ProgressBar, Orientation>(nameof(Orientation), Orientation.Horizontal);
public static readonly DirectProperty<ProgressBar, double> PercentageProperty =
AvaloniaProperty.RegisterDirect<ProgressBar, double>(
nameof(Percentage),
o => o.Percentage);
[Obsolete("To be removed when Avalonia.Themes.Default is discontinued.")]
public static readonly DirectProperty<ProgressBar, double> IndeterminateStartingOffsetProperty =
AvaloniaProperty.RegisterDirect<ProgressBar, double>(
@ -123,6 +132,12 @@ namespace Avalonia.Controls
p => p.IndeterminateEndingOffset,
(p, o) => p.IndeterminateEndingOffset = o);
public double Percentage
{
get { return _percentage; }
private set { SetAndRaise(PercentageProperty, ref _percentage, value); }
}
[Obsolete("To be removed when Avalonia.Themes.Default is discontinued.")]
public double IndeterminateStartingOffset
{
@ -165,6 +180,12 @@ namespace Avalonia.Controls
set => SetValue(ShowProgressTextProperty, value);
}
public string ProgressTextFormat
{
get => GetValue(ProgressTextFormatProperty);
set => SetValue(ProgressTextFormatProperty, value);
}
public Orientation Orientation
{
get => GetValue(OrientationProperty);
@ -245,6 +266,8 @@ namespace Avalonia.Controls
_indicator.Width = bounds.Width * percent;
else
_indicator.Height = bounds.Height * percent;
Percentage = percent * 100;
}
}
}

21
src/Avalonia.Themes.Default/Controls/ProgressBar.xaml

@ -1,4 +1,6 @@
<Styles xmlns="https://github.com/avaloniaui">
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:Avalonia.Controls.Converters;assembly=Avalonia.Controls">
<Design.PreviewWith>
<Border Padding="20">
<StackPanel Spacing="10">
@ -11,10 +13,13 @@
</Border>
</Design.PreviewWith>
<Style Selector="ProgressBar">
<Style.Resources>
<converters:StringFormatConverter x:Key="StringFormatConverter"/>
</Style.Resources>
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush4}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeAccentBrush}"/>
<Setter Property="Template">
<ControlTemplate>
<ControlTemplate TargetType="ProgressBar">
<Grid>
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}">
<Panel>
@ -23,7 +28,17 @@
</Panel>
</Border>
<LayoutTransformControl HorizontalAlignment="Center" VerticalAlignment="Center" IsVisible="{Binding ShowProgressText, RelativeSource={RelativeSource TemplatedParent}}" Name="PART_LayoutTransformControl">
<TextBlock Foreground="{DynamicResource ThemeForegroundBrush}" Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, StringFormat={}{0:0}%}" />
<TextBlock Foreground="{DynamicResource ThemeForegroundBrush}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource StringFormatConverter}">
<TemplateBinding Property="ProgressTextFormat"/>
<Binding Path="Value" RelativeSource="{RelativeSource TemplatedParent}"/>
<TemplateBinding Property="Percentage"/>
<TemplateBinding Property="Minimum"/>
<TemplateBinding Property="Maximum"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</LayoutTransformControl>
</Grid>
</ControlTemplate>

16
src/Avalonia.Themes.Fluent/Controls/ProgressBar.xaml

@ -1,5 +1,6 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:Avalonia.Controls.Converters;assembly=Avalonia.Controls"
x:CompileBindings="True">
<Design.PreviewWith>
<Border Padding="20">
@ -13,6 +14,9 @@
</Border>
</Design.PreviewWith>
<Style Selector="ProgressBar">
<Style.Resources>
<converters:StringFormatConverter x:Key="StringFormatConverter"/>
</Style.Resources>
<Setter Property="Foreground" Value="{DynamicResource SystemControlHighlightAccentBrush}" />
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundBaseLowBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource ProgressBarBorderThemeThickness}" />
@ -32,7 +36,17 @@
<Border x:Name="IndeterminateProgressBarIndicator2" CornerRadius="{TemplateBinding CornerRadius}" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />
</Panel>
<LayoutTransformControl x:Name="PART_LayoutTransformControl" HorizontalAlignment="Center" VerticalAlignment="Center" IsVisible="{TemplateBinding ShowProgressText}">
<TextBlock Foreground="{DynamicResource SystemControlForegroundBaseHighBrush}" Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, StringFormat={}{0:0}%}" />
<TextBlock Foreground="{DynamicResource SystemControlForegroundBaseHighBrush}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource StringFormatConverter}">
<TemplateBinding Property="ProgressTextFormat"/>
<Binding Path="Value" RelativeSource="{RelativeSource TemplatedParent}"/>
<TemplateBinding Property="Percentage"/>
<TemplateBinding Property="Minimum"/>
<TemplateBinding Property="Maximum"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</LayoutTransformControl>
</Panel>
</Border>

Loading…
Cancel
Save