如何仿效WPF控制台?(How to emulate a console in WPF?)

2019-07-20 02:59发布

我想一些技巧,在最正确的方向,甚至准备解决这个问题,我很卡(我只是初级/中级):

我想实现我的应用程序中的SSH。 使用SSH-后端工作正常等,但我被困在了前端。 什么WPF的组合将提出我适当的解决方案来模拟控制台? 抛开一个完整的终端仿真,我很乐意简单的readline /的WriteLine到的东西,看起来像一个控制台:-)

我的最好的方法却被而导致在4000个单细胞单字符80x50的网格,并且感觉就像一个总矫枉过正。

另一个想法是做一个控制台申请 绑定到另一个项目的WPF窗口。 但是...是,即使可能,如何?

Answer 1:

既然你想模仿一个控制台,我不喜欢这样。 请注意,你必须处理的命令和自己输出的结果。

page.xaml

<Window x:Class="ConsoleEmulation.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" MinHeight="350" MinWidth="525" Height="350" Width="525">
    <Grid>
        <ScrollViewer Name="Scroller" Margin="0" Background="Black">
            <StackPanel>
                <ItemsControl ItemsSource="{Binding ConsoleOutput, Mode=OneWay}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=.}" Foreground="White" FontFamily="Consolas"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
                <TextBox Text="{Binding ConsoleInput, Mode=TwoWay}" Background="Black" Foreground="White" FontFamily="Consolas" Name="InputBlock" BorderBrush="{x:Null}" SelectionBrush="{x:Null}" />
            </StackPanel>
        </ScrollViewer>
    </Grid>
</Window>

page.xaml.cs

public partial class MainWindow : Window
{
    ConsoleContent dc = new ConsoleContent();

    public MainWindow()
    {
        InitializeComponent();
        DataContext = dc;
        Loaded += MainWindow_Loaded;
    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        InputBlock.KeyDown += InputBlock_KeyDown;
        InputBlock.Focus();
    }

    void InputBlock_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            dc.ConsoleInput = InputBlock.Text;
            dc.RunCommand();
            InputBlock.Focus();
            Scroller.ScrollToBottom();
        }
    }
}

public class ConsoleContent : INotifyPropertyChanged
{
    string consoleInput = string.Empty;
    ObservableCollection<string> consoleOutput = new ObservableCollection<string>() { "Console Emulation Sample..." };

    public string ConsoleInput
    {
        get
        {
            return consoleInput;
        }
        set
        {
            consoleInput = value;
            OnPropertyChanged("ConsoleInput");
        }
    }

    public ObservableCollection<string> ConsoleOutput
    {
        get
        {
            return consoleOutput;
        }
        set
        {
            consoleOutput = value;
            OnPropertyChanged("ConsoleOutput");
        }
    }

    public void RunCommand()
    {
        ConsoleOutput.Add(ConsoleInput);
        // do your stuff here.
        ConsoleInput = String.Empty;
    }


    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged(string propertyName)
    {
        if (null != PropertyChanged)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}


Answer 2:

你知道吗,你可以通过使用AllocConsole显示从您的应用程序控制台窗口?

这是一个简单的方法来创建一个“双模式”的应用程序可以是一个控制台或Windows窗体应用程序。

[DllImport("kernel32")]
static extern bool AllocConsole();

或者你可以这样做:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="30"/>
    </Grid.RowDefinitions>
    <TextBlock Text="Console contents..." HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="ConsoleTextBlock"/>
    <DockPanel Grid.Row="1">
        <TextBox/>
    </DockPanel>
</Grid>

为了获得更好的外观,更换一个ListBox中的TextBlock,并相应风格的ItemTemplate中。



Answer 3:

我没有做我自己,但它是我的“我会做到这一点,如果我有时间” -projects之一。 因此,我仍然在寻找一个现有的实现:-P

不管怎么说一些想法:

该applroach使用视觉效果(即椭圆的TextBlocks)可能不是一个好主意。 试想想,什么都有,如果你想喜欢黑白200x100字符的情况发生。 甚至一个后备缓冲。 拿着这一切在内存+绘图它....这将是令人难以置信的慢。

因此,更好的(甚至是右)的做法是“画自己”。 由于WPF是backbuffered,你不希望显示的任意位最likly的方法是创建一个新的用户控件,并重写它的喷漆方法。 游马宁愿从Control派生,但用户控件可以有内容,这样你就可以显示类似的内部连接指示器图标。

建筑明智我建议创建一个dependecy特性缓冲ConsoleBuffer ),它保存控制台缓冲区模型。 另一个DP将举行左上当前位置定位long )。 它决定从哪里开始显示(当你看看后面)。 控制台模式我会做一个包含一类char[]Color[]一维)。 使用断行和\n字符以使线(因为这是一个控制台的字符)。 然后,如果你不调整缓冲区需要被重新分配它会重新流控制。 你可以用不同大小的** ** ConsoleBuffer的工作(对于不同数目的字符后面的样子)。

ConsoleBuffer.Write(string s)是你的方法做的东西。

也许最好是持有数组的数组char[][]表示线....但最多也就是在编程查不到。



文章来源: How to emulate a console in WPF?