Изменение значения прогрессбара в XAML с условный оператором

109
09 июня 2021, 08:00

Подскажите, можно-ли как-то изменить цвет прогрессбара, если его значение становится меньше 20 (и изменить обратно, если больше), используя XAML?

<ProgressBar Value="{Binding Path=Parameters.Satiety}" VerticalAlignment="Top"
             Foreground="Red"/>
Answer 1

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

abstract class ConverterBase : MarkupExtension, IValueConverter
{
    public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture);
    public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        => throw new NotImplementedException();
    public override object ProvideValue(IServiceProvider serviceProvider) => this;
}
class ComparingConverter : ConverterBase
{
    [Flags]
    public enum ConditionEnum
    {
        Nothing = 0,
        Equal = 1,
        Greater = 2,
        Less = 4,
        GreaterOrEqual = Greater | Equal,
        LessOrEqual = Less | Equal,
        NotEqual = Less | Greater,
        All = Less | Greater | Equal
    }
    public ConditionEnum Condition { get; set; }
    public int Value { get; set; }
    public ComparingConverter() { }
    public ComparingConverter(ConditionEnum condition, int value)
    {
        Condition = condition;
        Value = value;
    }
    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int v = (int)value;
        if (Condition.HasFlag(ConditionEnum.Equal) && v == Value) return true;
        if (Condition.HasFlag(ConditionEnum.Greater) && v > Value) return true;
        if (Condition.HasFlag(ConditionEnum.Less) && v < Value) return true;
        return false;
    }
}

Он захардкожен на использование int, но вы можете сделать его дженериком и заменить int на T : IComparable, но даже в этом случае вам придется сделать наследников с конкретными типами, потому что XAML не умеет работать с дженериками.

Теперь этот конвертер можно использовать так:

<ProgressBar Height="30" Value="{Binding V}">
    <ProgressBar.Style>
        <Style TargetType="ProgressBar">
            <Setter Property="Foreground" Value="Green"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding V, Converter={c:ComparingConverter Less, 50}}" Value="True">
                    <Setter Property="Foreground" Value="Yellow"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding V, Converter={c:ComparingConverter Less, 20}}" Value="True">
                    <Setter Property="Foreground" Value="Red"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ProgressBar.Style>
</ProgressBar>

READ ALSO
движение персонажа вместе с движущейся платформой unity3d

движение персонажа вместе с движущейся платформой unity3d

подскажите, как заставить персонажа двигаться вместе с платформой, на которой он стоит? пробовал припарентить - ничего не меняется, платформа...

101
Если источник null то мапить byte array тоже в null

Если источник null то мапить byte array тоже в null

Есть проблема с маппингом поля типа byte[8]Если значение поля источника равно null, то автомаппинг присваивает полю приемника значение 0x00000000

122
Эталонная реализация MVP в WinForms

Эталонная реализация MVP в WinForms

Хочу понять MVP паттерн на практике, но, кажется, не все понимаю правильно, поэтому простой вопрос: на форме есть кнопка и лейбл, так же есть...

106