0

私のアプリには、2 つの TextBlock と 1 つの ProgressBar を含む LongListSelector があります。TextBlocks は、ProgressBars Value および Maximum と同じ値にバインドされます。これは最初は機能しますが、ページを下にスクロールすると、進行状況バーに正しくない値が表示され始めますが、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

これは、悪い状態になると更新を停止するコントロール自体の問題のようです。この場合 (簡単に再現できます)、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}"/>
于 2013-06-06T07:57:48.140 に答える