【问题标题】:ProgressBar not updating on change to Maximum through bindingProgressBar 未通过绑定更改为最大值时更新
【发布时间】:2009-03-17 19:58:30
【问题描述】:
<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 属性发生变化时,Maximum 的转换器正在被调用。

基本上,ProgressBar 在值更改之前不会重绘。所以,如果我有 2 个管子并且 1 个失败了,即使我再添加 20 个管子,该条仍然是一半填充,直到 NumFailed 发生变化,然后更新比例。我尝试添加 NumFailed 属性的虚假通知,但这显然不起作用,因为值没有改变。

想法?

【问题讨论】:

    标签: wpf binding progress-bar


    【解决方案1】:

    看起来条形大小是在私有方法ProgressBar.SetProgressBarIndicatorLength 中计算的。它只能从OnValueChanged、OnTrackSizeChanged 和OnIsIndeterminateChanged 调用。

    您可以通过反射调用SetProgressBarIndicatorLength,或者循环调用它的属性之一。这很蹩脚,但看起来ProgressBar 的设计并不是为了让Maximum 和Minimum 在进行中进行更改。

    无论您选择哪种方法,您都可以使用DependencyPropertyDescriptor.AddValueChanged 确定Maximum 属性何时发生变化:

    DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(ProgressBar.MaximumProperty, typeof(ProgressBar)));
    if (dpd != null)
    {
       dpd.AddValueChanged(myProgressBar, delegate
       {
          // handle Maximum changes here
       });
    }
    

    【讨论】:

    • 我可以做一个简单的子类来触发这个你觉得吗?
    • 其实你不需要子类化,你可以为MaximumProperty获取一个DependencyPropertyDescriptor,然后调用AddValueChanged。我会把这个添加到我的帖子中。
    • 谢谢,我在委托中切换了 IsIndeterminate true/false。工作得很好。
    【解决方案2】:

    我无法让此处的解决方案发挥作用,但我找到了另一种解决方法。当我更改对象的数据源时,我的进度条不会更新(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}}" />
    

    【讨论】:

    • 我喜欢它,很好地结束了这种行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 2020-02-06
    • 1970-01-01
    • 2014-08-01
    相关资源
    最近更新 更多