Firstly, a disclaimer, what you're about to witness is my first bit of coding for almost 20 years. I'm new to C# and WPF, trying to get my head WPF is more than a challenge.
For the past month I've been working on a pet project console application, which has been performing well. I'm now trying to take it another step further by adding a modern GUI to the project.
I'd like to emulate a console (just the basic outpu functionality) by using a WPF textblock wrapped inside a scroller in a WPF window. You can see the original console application in action here to get a better idea of the kind of console output I'm trying to emulate. But I'm having a major problem with basic function calls, and I assume it's because I don't fully understand how WPF/C# work under the hood.
The Application starts in code via Main() like so:
class Program { public static ConsoleWindow MainConsole = new ConsoleWindow(); [STAThread] static void Main(string[] args) { Application MyApplication = new Application(); MyApplication.Run(MainConsole); // The following code does not work, it produces no output in the Textblock MainConsole.WriteLine("Crystal Console"); MainConsole.WriteLine("Version: " + Properties.Settings.Default.BuildVersion); MainConsole.WriteLine("Current Time: " + DateTime.Now); MainConsole.WriteLine("Last Login: " + Properties.Settings.Default.dateLastLogin); } } The problem is that the methods called don't seem to have any affect on the content of the textblock.
Although I'm about to give a lot of information just in case it's needed, the question itself is quite simple: Why does the Textblock update fine when taking content from a textbox control on the same window, but doesn't show any updates when the same method is called in Main() ?
For testing purposes the window has a few Textboxes that call the .WriteLine method inside the window, and THAT works, so I know there isn't a problem with the .WriteLine code, which you can see here:
public void WriteLine(string Message = null, string Sender = null) { _Console.AddElement(new ConsoleElement(Sender, Message + "\n")); _Console.DisplayContent(ConsoleTextBlock); ConsoleScroller.ScrollToEnd(); } Here is the code for the console itself in case it's needed, the class "ConsoleElement" is essentially just a object that contains the messages to be displayed in the Textblock as well as the formatting for each one.
class ConsoleStream { IList<ConsoleElement> ConsoleElements = new List<ConsoleElement>(); public void AddElement(ConsoleElement NewElement) { if (NewElement.Sender == null) // Sender is System not user. { NewElement.Content = " " + NewElement.Content; NewElement.Font = new FontFamily("Arial"); NewElement.FontSize = 12; } ConsoleElements.Add(NewElement); } public void ClearElements() { ConsoleElements.Clear(); } public void DisplayContent(TextBlock sender) { sender.Text = null; foreach (ConsoleElement Message in ConsoleElements) { //If message is a status update, i.e. has no sender, format it as a system message. if (Message.Sender != null) { sender.Inlines.Add(new Run(Message.Sender + ": ") { Foreground = Message.SenderColour, FontFamily = Message.Font, FontSize = Message.FontSize }); } //if message has a sender it's either the user or the AI. Format it as a user message. if (Message.Sender != null) sender.Inlines.Add(new Run(Message.Content) { Foreground = Message.ContentColour, FontFamily = Message.Font, FontSize = Message.FontSize }); else sender.Inlines.Add(new Run(Message.Content) { Foreground = Message.SystemColour, FontFamily = Message.Font, FontSize = Message.FontSize }); } } }