使用WPF窗口模拟控制台 [英] Emulating a console with a WPF window
问题描述
首先,免责声明,你要见证的是我第一次编码近20年。我是新来的C#和WPF,试图让我的头WPF是一个挑战。
在过去的一个月,我一直在一个宠物项目控制台应用程序,它已经表现良好。
我想仿效一个控制台(只是基本的outpu功能)通过在WPF窗口中使用包裹在滚动器内的WPF文本块。您可以看到原来的控制台应用程序在操作这里,以更好地了解控制台输出的种类我试图模拟。但我有一个主要的问题与基本的函数调用,我认为这是因为我不完全明白WPF / C#如何工作。
应用程序在代码中通过Main()代码:
类程序
{
public static ConsoleWindow MainConsole = new ConsoleWindow();
[STAThread]
static void Main(string [] args)
{
Application MyApplication = new Application();
MyApplication.Run(MainConsole);
//以下代码不工作,它在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);
}
}
问题是调用的方法似乎对文本块的内容有任何影响。
虽然我将提供很多信息,以防万一需要,问题本身很简单: 当在同一窗口中从文本框控件获取内容时,为什么Textblock更新正常,但在Main()中调用相同的方法时不会显示任何更新
为了测试的目的,窗口有几个Textboxes在窗口中调用.WriteLine方法,THAT工作,所以我知道.WriteLine代码没有问题,你可以看到这里:
public void WriteLine(string Message = null,string Sender = null)
{
_Console .AddElement(new ConsoleElement(Sender,Message +\\\
));
_Console.DisplayContent(ConsoleTextBlock);
ConsoleScroller.ScrollToEnd();
}
下面是控制台本身的代码, ConsoleElement本质上只是一个对象,它包含要在Textblock中显示的消息以及每个消息的格式。
class ConsoleStream
{
IList< ConsoleElement> ConsoleElements = new List< ConsoleElement>();
public void AddElement(ConsoleElement NewElement)
{
if(NewElement.Sender == null)//发件人是系统不是用户。
{
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(ConsoleElements中的ConsoleElement消息)
{
//如果消息是状态更新,即没有发送者,则将其格式化为系统消息。
if(Message.Sender!= null)
{
sender.Inlines.Add(new Run(Message.Sender +:){Foreground = Message.SenderColour,FontFamily = Message。 Font,FontSize = Message.FontSize});
}
//如果消息有一个发送者,它是用户或AI。将其格式化为用户消息。
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});
}
}
}
MyApplication.Run(MainConsole);
将代码移动到ConsoleWindow的load(或init)方法中
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 });
}
}
}
MyApplication.Run(MainConsole); takes control of the thread, the code after it doesn't execute until after you close the window.
Move the code to the load (or init) method of your ConsoleWindow
这篇关于使用WPF窗口模拟控制台的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!