WPF Привязка текстового блока к ProgressBar с процентом

#wpf #xaml #binding #textbox #progress-bar

#wpf #xaml #привязка #текстовое поле #индикатор выполнения

Вопрос:

У меня есть ProgressBar, который имеет максимум 10 000 (не 100). Я хочу, чтобы в привязанном текстовом поле отображался процент от текущего значения, а не само значение. Возможно ли это сделать в коде .xaml?

Ниже показано текущее значение моей ProgressBar. Я хочу, чтобы он отображал значение / максимум.

         <ProgressBar x:Name="calculationProgressBar" />
        <TextBlock x:Name="calculationProgressText" Text="{Binding ElementName=calculationProgressBar, Path=Value, StringFormat={}{0:0}%}" />
  

Комментарии:

1. Xaml не выполняет вычисления; эта функция выполняется либо с помощью конвертеров, либо с помощью привязки свойств.

Ответ №1:

Вы могли бы настроить простой IMultiValueConverter и передать свойства ProgressBars Value and Maximum

Пример:

Конвертер

 public class ValueToPercentConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double value = System.Convert.ToDouble(values[0]);
        double maximum = System.Convert.ToDouble(values[1]);
        return (value / maximum) * 100;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
  

Xaml:

 <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="100" Width="100">
    <Window.Resources>
        <local:ValueToPercentConverter x:Key="ValueToPercentConverter" />
    </Window.Resources>
    <StackPanel>
        <ProgressBar x:Name="calculationProgressBar" Maximum="10000" Value="2566" Height="40"/>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource ValueToPercentConverter}" StringFormat="{}{0}">
                    <Binding ElementName="calculationProgressBar" Path="Value"/>
                    <Binding ElementName="calculationProgressBar" Path="Maximum"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </StackPanel>
</Window>
  

Результат:
введите описание изображения здесь

Ответ №2:

Поскольку манипуляции в XAML невозможны, so converters — это подход для того же

Я попытался написать для вас простой код, используя строковый формат для уведомления о процентах StringFormat={}{0:P0}

Пример XAML

 <StackPanel>
    <StackPanel.Resources>
        <l:ScaleConverter x:Key="ScaleConverter"/>
    </StackPanel.Resources>
    <Slider x:Name="calculationSource" Maximum="10000"/>
    <TextBlock Text="{Binding ElementName=calculationSource, 
                              Path=Value, StringFormat={}{0:P0}, 
                              Converter={StaticResource ScaleConverter}, 
                              ConverterParameter=10000}" />
</StackPanel>
  

Я использовал ползунок вместо progressbar для упрощения демонстрации, вы можете использовать любой источник

укажите максимальное значение в параметре конвертера

а P0 в строковом формате означает процентный формат с точностью 0, например, 0%, вы можете сделать его P1 для 1 десятичного знака и так далее, например, 0.0%

класс конвертера

 class ScaleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return System.Convert.ToDouble(value) / System.Convert.ToDouble(parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
  

конвертер довольно прост, разделите значение на определенный масштаб.

Я надеюсь, что вы найдете это полезным для своей проблемы

Дополнительно

кроме того, если вы предпочитаете определять максимальный диапазон в одном месте, вы можете использовать ресурсы для того же

 <StackPanel>
    <StackPanel.Resources>
        <l:ScaleConverter x:Key="ScaleConverter"/>
        <sys:Double x:Key="maxRange">10000</sys:Double>
    </StackPanel.Resources>
    <Slider x:Name="calculationSource" Maximum="{StaticResource maxRange}"/>
    <TextBlock Text="{Binding ElementName=calculationSource, 
               Path=Value, StringFormat={}{0:P0}, 
               Converter={StaticResource ScaleConverter}, 
               ConverterParameter={StaticResource maxRange}}" />
</StackPanel>