0

我的应用程序中有一个 LongListSelector,其中包含两个 TextBlocks 和一个 ProgressBar。TextBlocks 绑定到与 ProgressBars 值和最大值相同的值。这最初有效,但是当我向下滚动页面时,进度条开始显示不正确的值,而 TextBlocks 保持正确。例如,它将显示 0 的值,但进度条将完全填满。

如何解决这个问题以让 ProgressBar 显示正确的值?

更新:正如你在这张照片中看到的。

请注意 ProgressBar 与其左/右的文本有何不同

这是导致问题的 XAML:

<TextBlock Text="{Binding Won}" Grid.Column="0"/>
<ProgressBar Maximum="{Binding Played}" Value="{Binding Won}" Grid.Column="1"/>
<TextBlock Text="{Binding Played}" Grid.Column="2"/>
4

1 回答 1

2

这看起来是控件本身的问题,当它进入错误状态时会停止更新。在这种情况下(我可以很容易地重现)绑定正在以错误的顺序更新属性(我们对此无能为力)并且ProgressBar停止更新。我拼凑了一个 ProgressBar 的快速子类来解决这个问题,但清理它留给你:)

public class RobusterProgressBar : ProgressBar
{

    new public static readonly DependencyProperty ValueProperty = 
        DependencyProperty.Register("Value", typeof(double), typeof(RobusterProgressBar), new PropertyMetadata(ValueChanged));

    new static void ValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = (RobusterProgressBar)d;
        control.Value = (double)e.NewValue;
    }

    new public static readonly DependencyProperty MaximumProperty = 
        DependencyProperty.Register("Maximum", typeof(double), typeof(RobusterProgressBar), new PropertyMetadata(MaximumChanged));

    static void MaximumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = (RobusterProgressBar)d;
        control.Maximum = (double)e.NewValue;
    }

    private double _value;
    new public double Value
    {
        get { return _value; }
        set { 
            _value = value;

            // only update the reflected Value if it is valid
            if (_value <= _maximum)
            {
                Update();
            }
        }
    }

    private double _maximum;
    new public double Maximum
    {
        get { return _maximum; }
        set { 
            _maximum = value;

            // only update the reflected maximum if it is valid
            if (_maximum >= _value)
            {
                Update();
            }
        }
    }

    private void Update()
    {
        // set all of the ProgressBar values in the correct order so that the ProgressBar 
        // never breaks and stops rendering
        base.Value = 0; // assumes no negatives
        base.Maximum = _maximum;
        base.Value = _value;
    }
}

基本上所有这一切都是将更新推迟到实际控制,直到所有数字都有效(基于基本value <= maximum规则)。在我的测试应用程序中,常规ProgressBar会在一段时间后消失,而这个版本不会。

顺便说一下,XAML 的用法是一样的:

<local:RobusterProgressBar Maximum="{Binding Played}" Value="{Binding Won}"/>
于 2013-06-06T07:57:48.140 回答