在我的WP8应用中,我使用后台转移服务和LongListSelector
ProgressBar
,因为它是DataTemplate
,以向用户显示项目下载进度。问题是ProgressBar
没有显示真正的进展,而是继续前后跳跃。
这是我的XAML。 LongListSelector
会定期收到BackgroundTransferRequest
的列表并使用
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
例如。为什么会发生这种事情,我该怎么做才能解决它?
答案 0 :(得分: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));
}
在此示例中,请求是绑定到ItemsSource的ObservableCollection。有了这个,您根本不需要手动更新 - BackgroundTransferRequest事件将驱动包装器在它们发生时通知prop更改。
我没有完全测试您的示例,但我怀疑您的问题与LongListSelector的UI虚拟化以及您不断重置ItemsSource的方式有关。另一种可能性是每次从BackgroundTransferService获取请求时,请求的顺序可能会发生变化。
祝你好运!