【问题标题】:updating progress bar using Task parallel library使用任务并行库更新进度条
【发布时间】:2017-12-20 00:16:00
【问题描述】:

我正在尝试更新进度条列表以在Xamarin.Forms 中使用Task Parallel Library 显示图像下载进度

目前我已经编写了一段代码,通过延迟来模拟下载过程。

这是我的Xaml 文件,其中有一个名为MediaListListView,每个项目都有一个标题和进度条。

<?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 取决于您的架构/设计决策,您可以分拆实现INotifyPropertyChangedMediaInfoViewModel,但这超出了您的问题范围。

标签: xamarin xamarin.forms task-parallel-library


【解决方案1】:

在您的视图模型中,您没有 mediaProgress。你应该添加

    Double _mediaProgress;
    public Double mediaProgress{
        get{
            return _mediaProgress;
        } set{
            _mediaProgress = value;
            OnPropertyChanged("Email");
        }
    }

然后在你的 all 方法中使用 mediaProgress 来设置进度。

【讨论】:

  • 我的mediaProgressmediaInfo 对象内,因为有多个进度条并且整个对象与MediaList 绑定
  • 好的,但是在您的 ViewModel 中,您没有将 mediaProgress 绑定到进度条
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 2014-11-16
相关资源
最近更新 更多