Заливка TextBlock в зависимости от значения ProgressBar

198
10 апреля 2018, 03:13

Есть TextBlock и ProgressBar в WPF. Фон у окна чёрный.

<TextBlock Text="My First Text" Foreground="White" TextAlignment="Center" VerticalAlignment="Center" FontSize="35"/>
<ProgressBar Width="600" Height="100"/>

Вопрос: Как сделать так, чтобы value у ProgressBar увеличивалось заполняя текст белым цветом слева направо?

Answer 1

Предлагаю такое простое решение:

Возьмем 2 TextBox и обернем их Gridом, причем в гриде 2 колонки и текстблоки расположены каждый в своей колонке. Текстблоки выравниваем левый по левому краю, правый - по правому. Ширину грида установим равной ширине одного текстблока. Всё: теперь простой регулировкой ширины колонки грида текстблоки будут торчать на ту или иную ширину. Нам понадобится лишь конвертер, который, в зависимости от значения ProgressBar, будет вычислять требуемую ширину колонки:

public class ProgressToWidthConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var minimum = (double)values[0];
        var maximum = (double)values[1];
        var value = (double)values[2];
        var width = (double)values[3];
        var part = (value - minimum) / (maximum - minimum);
        return new GridLength(part * width);
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Разметка:

<StackPanel Background="Gray">
    <Grid Width="{Binding ElementName=Template, Path=ActualWidth}">
        <Grid.Resources>
            <local:ProgressToWidthConverter x:Key="conv"/>
        </Grid.Resources>
        <Grid.ColumnDefinitions>
            <ColumnDefinition>
                <ColumnDefinition.Width>
                    <MultiBinding Converter="{StaticResource conv}">
                        <Binding ElementName="ProgressBar" Path="Minimum"/>
                        <Binding ElementName="ProgressBar" Path="Maximum"/>
                        <Binding ElementName="ProgressBar" Path="Value"/>
                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=Grid}" Path="ActualWidth"/>
                    </MultiBinding>
                </ColumnDefinition.Width>
            </ColumnDefinition>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Name="Template" Text="Some text" Foreground="White" HorizontalAlignment="Left"/>
        <TextBlock Grid.Column="1" Text="{Binding ElementName=Template, Path=Text}" Foreground="Black" HorizontalAlignment="Right"/>
    </Grid>
    <ProgressBar Name="ProgressBar" Height="10" Minimum="0" Maximum="100"/>
</StackPanel>

Поехали:

Минимальные модификации разметки позволяют добиться разных способов заливки текста: слева направо, справа налево, изнутри наружу, снаружи внутрь, сверзу вниз и т.д.:

READ ALSO
UTF8 строка, в нормальную .NET строку

UTF8 строка, в нормальную .NET строку

Я знаю как перекодировать строки, интересует следующее, какая стандартная кодировка у строкNET

228
Не отображается файл

Не отображается файл

Всем приветИмеется код в котором введенное значение кладется в файл it's password

222
WinApi нажатие Ctrl + -

WinApi нажатие Ctrl + -

Доброго времени сутокПишу небольшого автокликера для мобильной игры

244
Как запустить инсталятор внутри формы?

Как запустить инсталятор внутри формы?

Язык C# Как запустить exe инсталятор программы внутри формы своей программы? Это на тот случай если инсталятор не поддерживает тихий режим...

236