如何在 WPF 中获取 gui 元素的值?
How to get a value of gui element in WPF?
我正在尝试从调度程序获取元素的值。但是,我不知道如何在代码中稍后传递它。我想将进度传递给测试箱,了解已完成的工作。
每当我在主线程中使用 ProductId.Text
时,我都会得到值。
Task.Run(() =>
{
ProductId.Dispatcher.Invoke(() =>
{
string productId = ProductId.Text;});
Console.WriteLine($"Creating game {productId}");
});
我只是想稍后在代码中传递变量 productId。有什么想法吗?
根据评论,似乎有一个 long-running 后台进程需要 post 更新 UI。
这很容易做到,使用Progress class and the IProgress interface. This is described in Enabling Progress and Cancellation in Async APIs. The Progress can raise an event or call an Action<T>
callback on the thread it was created on. The IProgress.Report方法允许其他线程向Progress发送消息
从文章的示例中复制,此方法在后台线程中处理图像。每次它要报告进度,它调用progress.Report(message);
async Task<int> UploadPicturesAsync(List<Image> imageList, IProgress<string> progress)
{
int totalCount = imageList.Count;
int processCount = await Task.Run<int>(() =>
{
foreach (var image in imageList)
{
//await the processing and uploading logic here
int processed = await UploadAndProcessAsync(image);
if (progress != null)
{
var message=$"{(tempCount * 100 / totalCount)}";
progress.Report(message);
}
tempCount++;
}
return tempCount;
});
return processCount;
}
所需要做的就是在启动异步方法之前在 UI 线程中创建一个新的 Progress 实例:
void ReportProgress(string message)
{
//Update the UI to reflect the progress value that is passed back.
txtProgress.Text=message;
}
private async void Start_Button_Click(object sender, RoutedEventArgs e)
{
//construct Progress<T>, passing ReportProgress as the Action<T>
var progressIndicator = new Progress<int>(ReportProgress);
//load the image list *before* starting the background worker
var folder=txtPath.Text;
var imageList=LoadImages(folder);
//call async method
int uploads=await UploadPicturesAsync(imageList, progressIndicator);
}
正在阅读 UI
另一个重要的事情是 UploadPicturesAsync
不会 尝试从 UI 元素读取它的输入,无论它是什么。它接受它需要的输入,即图像列表作为参数。这使得在后台 运行 更容易,测试更容易,修改也更容易。
例如,可以修改代码以显示文件夹浏览器对话框,而不是从文本框中读取。
我正在尝试从调度程序获取元素的值。但是,我不知道如何在代码中稍后传递它。我想将进度传递给测试箱,了解已完成的工作。
每当我在主线程中使用 ProductId.Text
时,我都会得到值。
Task.Run(() =>
{
ProductId.Dispatcher.Invoke(() =>
{
string productId = ProductId.Text;});
Console.WriteLine($"Creating game {productId}");
});
我只是想稍后在代码中传递变量 productId。有什么想法吗?
根据评论,似乎有一个 long-running 后台进程需要 post 更新 UI。
这很容易做到,使用Progress class and the IProgress interface. This is described in Enabling Progress and Cancellation in Async APIs. The Progress can raise an event or call an Action<T>
callback on the thread it was created on. The IProgress.Report方法允许其他线程向Progress发送消息
从文章的示例中复制,此方法在后台线程中处理图像。每次它要报告进度,它调用progress.Report(message);
async Task<int> UploadPicturesAsync(List<Image> imageList, IProgress<string> progress)
{
int totalCount = imageList.Count;
int processCount = await Task.Run<int>(() =>
{
foreach (var image in imageList)
{
//await the processing and uploading logic here
int processed = await UploadAndProcessAsync(image);
if (progress != null)
{
var message=$"{(tempCount * 100 / totalCount)}";
progress.Report(message);
}
tempCount++;
}
return tempCount;
});
return processCount;
}
所需要做的就是在启动异步方法之前在 UI 线程中创建一个新的 Progress 实例:
void ReportProgress(string message)
{
//Update the UI to reflect the progress value that is passed back.
txtProgress.Text=message;
}
private async void Start_Button_Click(object sender, RoutedEventArgs e)
{
//construct Progress<T>, passing ReportProgress as the Action<T>
var progressIndicator = new Progress<int>(ReportProgress);
//load the image list *before* starting the background worker
var folder=txtPath.Text;
var imageList=LoadImages(folder);
//call async method
int uploads=await UploadPicturesAsync(imageList, progressIndicator);
}
正在阅读 UI
另一个重要的事情是 UploadPicturesAsync
不会 尝试从 UI 元素读取它的输入,无论它是什么。它接受它需要的输入,即图像列表作为参数。这使得在后台 运行 更容易,测试更容易,修改也更容易。
例如,可以修改代码以显示文件夹浏览器对话框,而不是从文本框中读取。