ProgressBar не обновляется при изменении на Maximum через привязку - PullRequest
3 голосов
/ 17 марта 2009
<ProgressBar Foreground="Red"
             Background="Transparent"
             Value="{Binding NumFailed, Mode=OneWay}"
             Minimum="0"
             Maximum="{Binding NumTubes, Mode=OneWay, Converter={x:Static wpftools:DebuggingConverter.Instance}, ConverterParameter=Failedprogressbar}"
             FlowDirection="RightToLeft"
             Style="{DynamicResource {x:Static wpftools:CustomResources.StyleProgressBarVistaKey}}" />

Вот так выглядит мой индикатор на данный момент. Стиль взят из http://mattserbinski.com/blog/look-and-feel-progressbar, а DebuggingConverter - это неоперативный преобразователь, который печатает значение, тип и параметр в консоль. Я убедился, что преобразователь для максимума вызывается при изменении свойства NumTubes.

По сути, ProgressBar не будет перерисовываться, пока значение не изменится. Таким образом, если у меня есть 2 пробирки, а 1 - неудачная, даже если я добавлю еще 20 пробирок, полоса будет заполнена наполовину, пока не изменится NumFailed, тогда пропорция обновится. Я попытался добавить ложные уведомления о свойстве NumFailed, но это, очевидно, не работает, так как значение не изменилось.

Идеи

Ответы [ 2 ]

4 голосов
/ 18 марта 2009

Похоже, размер бара рассчитывается в приватном методе ProgressBar.SetProgressBarIndicatorLength. Он вызывается только с OnValueChanged, OnTrackSizeChanged и OnIsIndeterminateChanged.

Вы можете вызвать SetProgressBarIndicatorLength через отражение или переключить одно из свойств, которое вызывает его. Это неубедительно, но не похоже, что ProgressBar был спроектирован так, что Maximum и Minimum будут изменены в середине хода.

Независимо от того, какой метод вы выберете, вы можете выяснить, когда свойство Maximum изменяется, используя DependencyPropertyDescriptor.AddValueChanged:

DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(ProgressBar.MaximumProperty, typeof(ProgressBar)));
if (dpd != null)
{
   dpd.AddValueChanged(myProgressBar, delegate
   {
      // handle Maximum changes here
   });
}
2 голосов
/ 19 августа 2011

У меня были проблемы с получением решения здесь, но я нашел другую работу вокруг. Мой индикатор выполнения не обновлялся, поскольку я изменил источник данных моего объекта (11 из 11 изменился бы на 10 из 10 и остановил индикатор выполнения), и понял, что мне вообще не нужно обновлять максимальное значение.

Вместо этого я использовал конвертер для значения, чтобы преобразовать его в процент, и установил мой максимум на 100. Результат отображает то же самое, но без ошибки при изменении максимального значения.

public class CreatureStaminaConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var creature = (CreatureBase.CreatureEntityData) value;
        double max = creature.entityData.MaxStat;
        return creature.CurrentStamina/max*100;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

 <ProgressBar Name="rpbStamina" Minimum="0" Maximum="100" Value="{Binding entityData, Converter={StaticResource CreatureStaminaConverter}}" />
...