0

在我的 WP8 应用程序中,我使用后台传输服务并LongListSelector使用ProgressBarDataTemplate向用户显示项目下载进度。问题是它ProgressBar并没有显示出真正的进步,而是不断地来回跳跃。

这是我的 XAML。LongListSelector定期接收BackgroundTransferRequest's 列表并用于 ProgressBar显示它们:

<phone:LongListSelector IsGroupingEnabled="False" x:Name="Views">
    <phone:LongListSelector.ListHeader>
        <StackPanel Style="{StaticResource M20}">
            <controls:TextTile Txt="Cancel downloads" Sign="x" Tap="CancelDownloads" />
        </StackPanel>
    </phone:LongListSelector.ListHeader>
    <phone:LongListSelector.ItemTemplate>
        <DataTemplate>
            <ProgressBar Maximum="{Binding TotalBytesToReceive}" Value="{Binding BytesReceived}" Minimum="0" />
        </DataTemplate>
    </phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>  

LongListSelector从类后面的代码中定期更新:

Views.ItemsSource = BackgroundTransferService.Requests.ToList()

LongListSelector仅在显示多个项目时才会出现此问题。ListBox例如,如果我尝试使用,一切正常。为什么会发生这种情况,我应该怎么做才能解决它?

4

1 回答 1

1

我无法将其放入评论中-试试这个:

public class BackgroundTransferRequestWrapper : INotifyPropertyChanged {

    private BackgroundTransferRequest _request;

    public BackgroundTransferRequestWrapper(BackgroundTransferRequest request) {
        _request = request;
        _request.TransferProgressChanged += OnTransferProgressChanged;
    }

    private void OnTransferProgressChanged(object sender, BackgroundTransferEventArgs e) {
        BytesReceived = _request.BytesReceived;
        TotalBytesToReceive = _request.TotalBytesToReceive;
    }

    private long bytesReceived = 0;
    public long BytesReceived {
        get { return bytesReceived; }
        set {
            bytesReceived = value;
            OnPropertyChanged();
        }
    }

    private long totalBytesToReceive = 0;
    public long TotalBytesToReceive {
        get { return totalBytesToReceive; }
        set { totalBytesToReceive = value;
        OnPropertyChanged();}
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

与其在计时器上重置 ItemsSource,不如这样做:

    foreach (var request in BackgroundTransferService.Requests) {
        Requests.Add(new BackgroundTransferRequestWrapper(request));
    }

在此示例中,Requests是绑定到您的 ItemsSource 的 ObservableCollection。有了这个,你根本不需要手动更新——BackgroundTransferRequest 事件将驱动包装器在 prop 更改发生时通知它们。

我没有完全测试您的示例,但我怀疑您的问题与 LongListSelector 的 UI 虚拟化以及您不断重置 ItemsSource 的方式有关。另一种可能性是每次从 BackgroundTransferService 获取请求时,请求的顺序可能会发生变化。

祝你好运!

于 2013-03-01T14:12:26.090 回答