Как привязать ProgressBar Maximum минус значение к текстовому блоку в WPF - PullRequest
0 голосов
/ 02 июля 2019

В смеси Expression у меня есть один прогрессбар и два текстовых блока. Я привязал первый текстовый блок к свойству Value. Мне нужно привязать второй текстовый блок к свойствам Maximum-Value, чтобы прочитать оставшееся количество для заполнения progressBar. Как я могу сделать это в XAML?

Поскольку я хочу видеть изменения в представлении конструктора, пока я изменяю значение progressBar

Вот вид: https://i.imgur.com/yTF1rRl.png

Код:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="mobSizing.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640" Height="480">

    <Grid x:Name="LayoutRoot">
        <ProgressBar x:Name="progressBar" Height="41" Margin="84,77,125,0" VerticalAlignment="Top" Value="66"/>
        <TextBlock x:Name="Value" HorizontalAlignment="Left" Height="40" Margin="106,142,0,0" TextWrapping="Wrap" Text="{Binding Value, ElementName=progressBar}" VerticalAlignment="Top" Width="182" Foreground="#FF40B617"/>
        <TextBlock x:Name="Left" HorizontalAlignment="Right" Height="40" Margin="0,145,53,0" TextWrapping="Wrap" Text="{Binding Value, ElementName=progressBar}" VerticalAlignment="Top" Width="182" Foreground="#FF8F8F8F"/>
    </Grid>
</Window>

1 Ответ

1 голос
/ 02 июля 2019

Вот подход, основанный на нескольких преобразователях.

Markup:

<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <RowDefinition Height="60"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <ProgressBar x:Name="progressBar" Height="41"  
                 Grid.ColumnSpan="3"
                 Value="66"/>
    <TextBlock x:Name="Value"
               Grid.Column="0" 
               Grid.Row="1"
               Text="{Binding Value, ElementName=progressBar}" VerticalAlignment="Top"  
               TextAlignment="Center"
               Foreground="#FF40B617"/>
    <TextBlock x:Name="Left" 
               Grid.Column="2" 
               Grid.Row="1"
               TextAlignment="Center"
               VerticalAlignment="Top" 
               Foreground="#FF8F8F8F">
        <TextBlock.Text>
            <MultiBinding Converter="{local:AmountLeftMultiConverter}" StringFormat="{}{0:n0}">
                <Binding Path="Maximum" ElementName="progressBar"/>
                <Binding Path="Value"  ElementName="progressBar"/>
            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>
</Grid>

Конвертер вычтет все, что вторая привязка даст ему из первой. Эти значения передаются в массиве на мультиконвертер.

Конвертер. Мой находится в приложении нуля, поэтому ваше пространство имен будет другим:

    using System;
    using System.Globalization;
    using System.Windows.Data;
    using System.Windows.Markup;

    namespace wpf_99
    {
        public class AmountLeftMultiConverter : MarkupExtension, IMultiValueConverter
        {
            public double Multiplier { get; set; }

            public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
            {
                double toAdd = System.Convert.ToDouble(values[0]);
                double toSubtract = System.Convert.ToDouble(values[1]);

                return toAdd - toSubtract;
            }

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

            public override object ProvideValue(IServiceProvider serviceProvider)
            {
                return this;
            }
        }
    }

Поскольку это также является значительным расширением, вам не нужно объявлять его в каких-либо ресурсах перед использованием.

...