【发布时间】:2017-12-20 00:16:00
【问题描述】:
我正在尝试更新进度条列表以在Xamarin.Forms 中使用Task Parallel Library 显示图像下载进度
目前我已经编写了一段代码,通过延迟来模拟下载过程。
这是我的Xaml 文件,其中有一个名为MediaList 的ListView,每个项目都有一个标题和进度条。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ImageTask.View.ImageTaskView">
<ContentPage.Content>
<ListView ItemsSource="{Binding MediaList}" CachingStrategy = "RecycleElement" VerticalOptions="FillAndExpand" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical">
<Label Text = "{Binding mediaName}" FontSize="22" />
<ProgressBar Progress="{Binding mediaProgress}"></ProgressBar>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
这是我的视图模型,我在其中创建了一个操作块,它获取整个媒体对象列表并尝试更新进度条。
但是,我的主要问题是我无法在我的 UI 中看到更新的进度,所以我不知道如何更新我的 UI。
public class ImageTaskViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private IList<MediaInfo> _mediaList;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public IList<MediaInfo> MediaList
{
get { return _mediaList; }
set
{
_mediaList = value;
OnPropertyChanged("MediaList");
}
}
public ImageTaskViewModel()
{
Action<IList<MediaInfo>> progressActionBlock = mediaInfoList =>
{
// infinite loop to simulate download
while (true)
{
IEnumerator<MediaInfo> dataList = mediaInfoList.GetEnumerator();
Task.Delay(2000).Wait();
while (dataList.MoveNext())
{
MediaInfo mediaInfo = dataList.Current;
Debug.WriteLine("media name " + mediaInfo.mediaName + " progress " + mediaInfo.mediaProgress);
if (mediaInfo.mediaProgress == 1)
{
Debug.WriteLine("media name " + mediaInfo.mediaName + " Done ");
break;
}
else
{
mediaInfo.mediaProgress = mediaInfo.mediaProgress + 0.1;
}
}
}
};
var opts = new ExecutionDataflowBlockOptions()
{
MaxDegreeOfParallelism = 2
};
var progressAction = new ActionBlock<IList<MediaInfo>>(progressActionBlock, opts);
MediaList = new List<MediaInfo>();
for (int i = 1; i < 6; i++)
{
MediaInfo mediaInfo = new MediaInfo();
mediaInfo.mediaName = i.ToString();
MediaList.Add(mediaInfo);
}
// Exectue Action block
progressAction.Post(MediaList);
}
}
MediaInfo的型号:
public class MediaInfo
{
public string mediaId { get; set; }
public string mediaName { get; set; }
public string mediaPath { get; set; }
public byte[] mediaStream { get; set; }
public double mediaProgress { get; set; } = 0.1;
}
【问题讨论】:
-
你需要做的就是让
MediaInfo实现INotifyPropertyChanged。 -
仅供参考:我之前的评论仅适用于模拟您的下载的示例代码的行为如您所说的那样。
-
但是我已经在视图模型中实现了
INotifiyPropertyChanged,所以你也想在模型中实现它吗? -
是的,目前唯一的“属性”报告更改是
MediaList,因此唯一会发送的通知是您是否完全替换该列表。使用ObservableCollection来获取集合更改的通知,并在模型上实现INotifyPropertyChanged以获取模型更改的通知。模型是否应该实现INotifyPropertyChanged取决于您的架构/设计决策,您可以分拆实现INotifyPropertyChanged的MediaInfoViewModel,但这超出了您的问题范围。
标签: xamarin xamarin.forms task-parallel-library