从另一个 class 访问 UI 控件
Access UI Control from another class
我想从另一个 class 更新我的进度视图,但不知道如何正确地做到这一点。
在我的 ViewController 中,我有一个启动任务的按钮,它从硬编码 link
下载文件
public void downloadTask()
{
NSUrl url = NSUrl.FromString("https://www.dropbox.com/s/5fsciuo0nprzvu6/TestDoc.docx?dl=0");
var config = NSUrlSessionConfiguration.DefaultSessionConfiguration;
NSUrlSession session = NSUrlSession.FromConfiguration(config, (new SimpleSessionDelegate() as INSUrlSessionDelegate), new NSOperationQueue());
var downloadTask = session.CreateDownloadTask(NSUrlRequest.FromUrl(url));
downloadTask.Resume();
}
在我的 SimpleSessionDelegate class 中,我想在 DidWriteData 方法中更新我的进度视图。
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();
}
}
在您的 Page.xaml
中执行此操作:
<ContentPage .... >
...
<ProgressBar Progress="{Binding ProgValue, Mode=TwoWay}" />
...
</ContentPage>
然后在 Page.xaml.cs
中执行此操作:
...
public partial class Page : ContentPage
{
InitializeComponent();
BindingContext = new PageViewModel();
}
...
现在您需要 PageViewModel
class 在您的数据(模型)和您的视图之间创建一条路径:
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(模型-视图-视图-模型)——正式名称为 MVC(模型-视图-控制器)
您可以尝试使用 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;
}
那么你可以在方法DidWriteData()
:
有数据进来的时候触发这个事件
float progress = (float)totalBytesWritten / totalBytesExpectedToWrite;
DownloadEvent(progress);
最后一步是在您的 ViewController 中订阅此活动,例如:
var myViewModel = new ViewModel();
MyViewModel.DownloadEvent += (progress) =>
{
MyProgress.Progress = progress;
};
myViewModel.downloadTask();
我想从另一个 class 更新我的进度视图,但不知道如何正确地做到这一点。
在我的 ViewController 中,我有一个启动任务的按钮,它从硬编码 link
下载文件public void downloadTask()
{
NSUrl url = NSUrl.FromString("https://www.dropbox.com/s/5fsciuo0nprzvu6/TestDoc.docx?dl=0");
var config = NSUrlSessionConfiguration.DefaultSessionConfiguration;
NSUrlSession session = NSUrlSession.FromConfiguration(config, (new SimpleSessionDelegate() as INSUrlSessionDelegate), new NSOperationQueue());
var downloadTask = session.CreateDownloadTask(NSUrlRequest.FromUrl(url));
downloadTask.Resume();
}
在我的 SimpleSessionDelegate class 中,我想在 DidWriteData 方法中更新我的进度视图。
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();
}
}
在您的 Page.xaml
中执行此操作:
<ContentPage .... >
...
<ProgressBar Progress="{Binding ProgValue, Mode=TwoWay}" />
...
</ContentPage>
然后在 Page.xaml.cs
中执行此操作:
...
public partial class Page : ContentPage
{
InitializeComponent();
BindingContext = new PageViewModel();
}
...
现在您需要 PageViewModel
class 在您的数据(模型)和您的视图之间创建一条路径:
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(模型-视图-视图-模型)——正式名称为 MVC(模型-视图-控制器)
您可以尝试使用 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;
}
那么你可以在方法DidWriteData()
:
float progress = (float)totalBytesWritten / totalBytesExpectedToWrite;
DownloadEvent(progress);
最后一步是在您的 ViewController 中订阅此活动,例如:
var myViewModel = new ViewModel();
MyViewModel.DownloadEvent += (progress) =>
{
MyProgress.Progress = progress;
};
myViewModel.downloadTask();