LongListSelector中的进度条不正确

时间:2013-06-04 19:09:18

标签: c# windows-phone-7

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

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

更新:正如您在此图片中所见。

Notice how the ProgressBar is different from the text on its left/right

这是造成问题的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"/>

1 个答案:

答案 0 :(得分:2)

这看起来是控件本身的问题,当它进入错误状态时会停止更新。在这种情况下(我可以轻松地重复)Binding正在以错误的顺序更新属性(我们无法真正做到这一点)并且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}"/>