ProgressBar не обновляется при изменении на Максимум через привязку

<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 пробирки, и одна из них вышла из строя, даже если я добавлю еще 20 пробирок, полоса все равно будет заполнена наполовину до тех пор, пока значение NumFailed не изменится, а затем пропорция будет обновлена. Я пробовал добавлять ложные уведомления о свойстве NumFailed, но это, по-видимому, не работает, поскольку значение не изменилось.

Идеи?


person Thomas    schedule 17.03.2009    source источник


Ответы (2)


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

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

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

DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(ProgressBar.MaximumProperty, typeof(ProgressBar)));
if (dpd != null)
{
   dpd.AddValueChanged(myProgressBar, delegate
   {
      // handle Maximum changes here
   });
}
person Robert Macnee    schedule 17.03.2009
comment
Как вы думаете, можно ли сделать простой подкласс, чтобы вызвать это? - person Thomas; 18.03.2009
comment
Фактически, вам не нужно создавать подкласс, вы можете получить DependencyPropertyDescriptor для MaximumProperty и вызвать AddValueChanged. Я добавлю это в свой пост. - person Robert Macnee; 18.03.2009
comment
Спасибо, я переключил IsIndeterminate на true / false внутри делегата. Отлично работает. - person Thomas; 18.03.2009

У меня возникли проблемы с тем, чтобы решение здесь работало, но я нашел другую работу. Мой индикатор выполнения не обновлялся, поскольку я изменил источник данных своего объекта (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}}" />
person Richard Maxwell    schedule 19.08.2011
comment
Мне это нравится, приятное поведение в конце концов. - person Thomas; 21.08.2011