【问题标题】:Progress Bar is incorrect in LongListSelectorLongListSelector 中的进度条不正确
【发布时间】:2013-06-06 15:57:48
【问题描述】:

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

如何解决这个问题以让 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"/>

【问题讨论】:

  • 这看起来像是一个绑定问题,你能分享一下相关的 XAML / 背后的代码吗?
  • 我已将 XAML 添加到我的原始帖子中。您需要整个 ItemTemplate 还是会这样做?
  • 按照 Oren 的建议,如果您在调试时查看“输出”窗口,您会看到任何绑定错误吗?
  • 不,我在运行时没有出错。

标签: c# windows-phone-7


【解决方案1】:

这似乎是控件本身的问题,当它进入错误状态时会停止更新。在这种情况下(我可以很容易地重现)绑定正在以错误的顺序更新属性(我们对此无能为力)并且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 &lt;= maximum 规则)。在我的测试应用程序中,常规的ProgressBar 会在一段时间后死掉,而这个版本不会。

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

<local:RobusterProgressBar Maximum="{Binding Played}" Value="{Binding Won}"/>

【讨论】:

  • 谢谢,这正是我所需要的。像魅力一样工作。
猜你喜欢
  • 2021-04-15
  • 1970-01-01
  • 2017-04-15
  • 1970-01-01
  • 2017-02-22
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
  • 2018-10-27
相关资源
最近更新 更多