Reputation: 1614
I am using WPF and would like it to act like a console application. Please bear with me as this is my first time trying to use WPF. Basically what I have for now is a full-screen white window with a textbox inside it.
I have a ContentRendered event that calls a method. This method needs to do a number of processes (including launching and killing some applications). Between each process and another, it's changing the textBox.Text and appending the status, sort of "Process x ready..." etc.
The problem I'm having is that the window is loading with an empty textbox and after all the processes are ready, the textBox.Text changes are all rendered at once right at the end.
What am I doing wrong?
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";
}
}
Upvotes: 1
Views: 421
Reputation: 1973
Try this.
Do the work in a background thread using Task.Run().
Since Logger methods now get called on a non-UI thread, extra work is needed to marshal the call back to the UI thread, so we use 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;
}
}
Upvotes: 2