c# - WPF 文本框更改直到所有处理完成后才会呈现
问题描述
我正在使用 WPF,并希望它像控制台应用程序一样工作。请多多包涵,因为这是我第一次尝试使用 WPF。基本上我现在拥有的是一个全屏的白色窗口,里面有一个文本框。
我有一个调用方法的 ContentRendered 事件。这种方法需要做一些进程(包括启动和杀死一些应用程序)。在每个进程和另一个进程之间,它正在更改 textBox.Text 并附加状态,类似于“Process x ready ...”等。
我遇到的问题是窗口正在加载一个空的文本框,并且在所有进程都准备好之后, textBox.Text 更改都在最后立即呈现。
我究竟做错了什么?
public partial class MainWindow : Window
{
public MainWindow()
{
Topmost = true;
InitializeComponent();
}
private async void Window_ContentRendered(object sender, System.EventArgs e)
{
await ProcessFlow.Start();
}
}
class ProcessFlow
{
public async static Task Start()
{
await Logger.Write("Opening App...");
ProcessStartInfo startInfo = new ProcessStartInfo(@"C:\Program Files (x86)\App\App.exe");
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
using (var process = Process.Start(startInfo))
{
await Logger.WriteLine(" done!");
Thread.Sleep(30000);
await Logger.Write("Closing App...");
process.Kill();
await Logger.WriteLine(" done!");
}
}
}
public class Logger
{
static MainWindow Form = Application.Current.Windows[0] as MainWindow;
public async static Task Write(string text)
{
Form.textBox1.Text += text;
}
public async static Task WriteLine(string text)
{
Form.textBox1.Text += text + "\r\n";
}
}
解决方案
尝试这个。
使用 Task.Run() 在后台线程中完成工作。
由于现在在非 UI 线程上调用 Logger 方法,因此需要额外的工作来将调用编组回 UI 线程,因此我们使用 Dispatcher.InvokeAsync()。
public partial class MainWindow : Window
{
Logger logger;
public MainWindow()
{
InitializeComponent();
logger = new Logger(this);
}
private async void Window_ContentRendered(object sender, EventArgs e)
{
ProcessFlow processFlow = new ProcessFlow(logger);
await processFlow.Start();
}
}
class ProcessFlow
{
private readonly Logger logger;
public ProcessFlow(Logger logger)
{
this.logger = logger;
}
public Task Start()
{
return Task.Run(
async () =>
{
await logger.Write("Opening App...");
ProcessStartInfo startInfo = new ProcessStartInfo(@"notepad.exe")
{
UseShellExecute = true
};
// startInfo.WindowStyle = ProcessWindowStyle.Hidden;
using (var process = Process.Start(startInfo))
{
await logger.WriteLine(" done!");
await Task.Delay(2000);
await logger.Write("Closing App...");
process.Kill();
await logger.WriteLine(" done!");
}
}
);
}
}
public class Logger
{
private readonly MainWindow window;
public Logger(MainWindow window)
{
this.window = window;
}
public Task Write(string text)
{
return window.Dispatcher.InvokeAsync(() => window.textBox1.Text += text).Task;
}
public Task WriteLine(string text)
{
return window.Dispatcher.InvokeAsync(() => window.textBox1.Text += text + "\r\n").Task;
}
}
推荐阅读
- html - 如何创建一个固定的 div 和第二个可滚动的?
- c# - 使用 C# Array.ConvertAll 时,Visual Studio 2017 调试器不显示变量
- r - 如何在 R 中的数据帧上应用 CNN?
- spring-boot - 从源码讨论SpringApplication的run方法是否会执行两次
- python - 静态文件问题,除了一些文件 style.css 和 js 外,所有内容都已加载
- ruby - 2020 年的 Ruby 2.2.3
- paypal - 对第三方的大规模支付建议
- python - 如何在 Tkinter 的窗口中更改具有图形的子图参数?例如我想添加 xlabel 和 ylabel
- c++11 - 在 C++ 中使用 2D 数组指针复制结构 - 指针算术
- java - 使用 SaxParser 修改 xml 属性