从另一个类访问UI控件

时间:2018-01-29 16:19:13

标签: ios xamarin background nsurlsession

我想从另一个班级更新我的进度视图,但不知道该怎么做。

在我的ViewController中,我有一个启动任务的按钮,从硬编码链接下载文件

public class SimpleSessionDelegate : NSUrlSessionDownloadDelegate
    {
        public override void DidFinishDownloading(NSUrlSession session, NSUrlSessionDownloadTask downloadTask, NSUrl location)
        {
            var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            var destinationPath = Path.Combine(documents, "Sample.docx");

            if (File.Exists(location.Path))
            {
                NSFileManager fileManager = NSFileManager.DefaultManager;
                NSError error;

                fileManager.Remove(destinationPath, out error);

                bool success = fileManager.Copy(location.Path, destinationPath, out error);

                if (!success)
                {
                    Console.WriteLine("Error during the copy: {0}", error.LocalizedDescription);
                }
            }
        }
        public override void DidWriteData(NSUrlSession session, NSUrlSessionDownloadTask downloadTask, long bytesWritten, long totalBytesWritten, long totalBytesExpectedToWrite)
        {
            new System.Threading.Thread(new System.Threading.ThreadStart(() =>
            {
                InvokeOnMainThread(() =>
                {
                    //how to access UI?
                });
            })).Start();
        }
    }

在我的SimpleSessionDelegate类中,我想在DidWriteData方法中更新我的进度视图。

If

2 个答案:

答案 0 :(得分:2)

Page.xaml执行此操作:

<ContentPage .... >
    ...
    <ProgressBar Progress="{Binding ProgValue, Mode=TwoWay}" />
    ...
</ContentPage>

然后在Page.xaml.cs中执行此操作:

...
public partial class Page : ContentPage
{
    InitializeComponent();
    BindingContext = new PageViewModel();
}
...

现在您需要PageViewModel课程来创建数据(模型)与您查看之间的路径:

using MvvmHelper;
using System;

namespace MyApp.ViewModels
{
    ...
    public class PageViewModel : BaseViewModel
    {
        ...
        public static int ProgValue { get; set; }
        ...
    }
}

现在,如果您从应用的每个位置更新ProgValue的值,它将自动更新进度条。

要使用BaseViewModel,您需要安装
Mvvm Helper
或者在包管理器控制台中输入:
Install-Package Refractored.MvvmHelpers

这种架构称为MVVM(Model-View-View-Model) - 正式名称为MVC(Model-View-Controller)

答案 1 :(得分:2)

您可以尝试使用Event来更改ViewController的UIProgressView的进度。

首先在ViewModel中定义一个事件:

public delegate void DownloadProgressDelegate(float progress);
public event DownloadProgressDelegate DownloadEvent;

其次,将此事件传递给下载委托文件:

NSUrlSession session = NSUrlSession.FromConfiguration(config, (new SimpleSessionDelegate(DownloadEvent) as INSUrlSessionDelegate), new NSOperationQueue());
//Here is your SimpleSessionDelegate
event ViewModel.DownloadProgressDelegate DownloadEvent;
public SimpleSessionDelegate(ViewModel.DownloadProgressDelegate downloadEvent)
{
    DownloadEvent = downloadEvent;
}

然后,当数据进入menthod DidWriteData()时,您可以触发此事件:

float progress = (float)totalBytesWritten / totalBytesExpectedToWrite;
DownloadEvent(progress);

最后一步是在ViewController中订阅此事件,如:

var myViewModel = new ViewModel();
MyViewModel.DownloadEvent += (progress) =>
{
    MyProgress.Progress = progress;
};
myViewModel.downloadTask();