使用WPF窗口模拟控制台 [英] Emulating a console with a WPF window

查看:248
本文介绍了使用WPF窗口模拟控制台的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,免责声明,你要见证的是我第一次编码近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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆