WPF-实现仿Linux终端

1 篇文章 0 订阅
1 篇文章 0 订阅

WPF-实现仿Linux的shell功能(终端terminal)

很多软件,如VS,IDEA都有类似Linux的shell功能,那么怎样用C#来实现该功能呢,在网上找了一下,基本没有,于是自己花了点时间大致实现了该功能,如果有时间,之后还会完善和优化一下,欢迎大家指点.

界面代码

界面很简单,基本就使用了一个TextBox。

<Window
    x:Class="ch4_Terminal.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:ch4_Terminal.Views"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="20*" />
        </Grid.RowDefinitions>
        <TextBlock Text="终端样式:" />
        <Border
            x:Name="bd"
            Grid.Row="1"
            Background="Black"
            CornerRadius="10">
            <TextBox
                x:Name="MyTextBox"
                Margin="5"
                AcceptsReturn="True"
                Background="Black"
                BorderBrush="White"
                Foreground="White"
                KeyDown="MyTextBox_KeyDown"
                PreviewKeyDown="MyTextBox_PreviewKeyDown"
                PreviewMouseDown="MyTextBox_PreviewMouseDown"
                TextWrapping="Wrap"
                VerticalScrollBarVisibility="Hidden" />
        </Border>
    </Grid>
</Window>

后台逻辑代码

using ch4_Terminal.Commoms;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace ch4_Terminal.Views
{
    
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public int enterTimes = 0;
        Timer timer = new Timer();
        public double positionX=0;

        private int i = 0;
        private int j = 0;
        private int m = 0;
        private int n = 0;

        private List<string> CmdList = new List<string>();
        private string Cmd;

        public MainWindow()
        {
            InitializeComponent();
            CmdList.Clear();
        }

        private void MyTextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            //Point pt = e.GetPosition(this);
            var a = MyTextBox.Text;
            if (a == "")
            {
                this.MyTextBox.Text = ">";
            }
            else 
            {
                if (this.MyTextBox.Text.EndsWith(">"))
                {
                    return;
                }else if (this.MyTextBox.Text.EndsWith("\n"))
                {
                    this.MyTextBox.Text += "\n\r>";
                }

            }
        }

        private void MyTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            //Enter
            if (e.KeyStates == Keyboard.GetKeyStates(Key.Enter))
            {
                e.Handled = true;
                var a = MyTextBox.Text;
                Cmd = a.Substring(a.LastIndexOf(">")+1,MyTextBox.Text.Length- a.LastIndexOf(">")-1);
                if (a.EndsWith(">"+Cmd) && VerifyCmd(Cmd))
                {
                    //MessageBox.Show("OK");

                    this.MyTextBox.Text += "\n" + $"{ DateTime.Now:yyyy - MM - dd HH: mm: ss}:" + $"Start \"{Cmd}\" Command is ok!\n\r>";
                    CmdList.Add(Cmd);
                    MyTextBox.SelectionStart = MyTextBox.Text.Length;
                }

                if (a.EndsWith(">clc"))
                {
                    this.MyTextBox.Text = ">";
                    CmdList.Clear();
                    MyTextBox.SelectionStart = MyTextBox.Text.Length;
                }
            }

            //Backspace
            if (e.KeyStates == Keyboard.GetKeyStates(Key.Back))
            {
                e.Handled = true;
                var a = MyTextBox.Text;
                if (a.EndsWith(">"))
                {
                    MyTextBox.SelectionStart = MyTextBox.Text.Length;
                    return;
                } else
                {
                    var str = a.Split('>');
                    var charArray = str[str.Length - 1].ToCharArray();
                    var NewChar = new char[charArray.Length - 1];
                    if (charArray.Length>0)
                    {
                        Array.Copy(charArray, NewChar, charArray.Length-1);
                        string s = new string(NewChar);
                        MyTextBox.Text = a.Remove(a.LastIndexOf(">")) + ">" + s;
                        MyTextBox.SelectionStart = MyTextBox.Text.Length;
                    }
                    else
                    {
                        return;
                    }
                }
            }

            //Left
            if (e.KeyStates == Keyboard.GetKeyStates(Key.Left))
            {
                i++;
                e.Handled = true;
                var a = MyTextBox.Text;
                if (a.EndsWith(">"))
                {
                    MyTextBox.SelectionStart = MyTextBox.Text.Length;
                    return;
                }else
                {
                    var str = a.Split('>');
                    var charArray = str[str.Length - 1].ToCharArray();
                    if (i<=charArray.Length)
                    {
                        MyTextBox.SelectionStart = MyTextBox.Text.Length - i;
                        j = charArray.Length - i;
                        return;
                    }
                }
            }

            //Right
            if (e.KeyStates == Keyboard.GetKeyStates(Key.Right))
            {
                j++;
                e.Handled = true;
                var a = MyTextBox.Text;
                if (a.EndsWith(">"))
                {
                    MyTextBox.SelectionStart = MyTextBox.Text.Length;
                    return;
                }
                else
                {
                    var str = a.Split('>');
                    var charArray = str[str.Length - 1].ToCharArray();
                    if (j <= charArray.Length)
                    {
                        MyTextBox.SelectionStart = MyTextBox.Text.Length - charArray.Length + j;
                        i = charArray.Length - j;
                        return;
                    }
                }
            }

            //Up
            if (e.KeyStates == Keyboard.GetKeyStates(Key.Up))
            {
                m++;
                e.Handled = true;
                var a = MyTextBox.Text;
                if (a.EndsWith(">"))
                {
                    if (CmdList.Count > 0 && (m - 1 < CmdList.Count))
                    {
                        MyTextBox.Text += CmdList[CmdList.Count - m];
                        n = CmdList.Count - m;
                    }
                    MyTextBox.SelectionStart = MyTextBox.Text.Length;
                }
                else
                {
                    MyTextBox.Text = a.Remove(a.LastIndexOf(">")) + ">" ;
                    if (CmdList.Count > 0 && (m - 1 < CmdList.Count))
                    {
                        MyTextBox.Text += CmdList[CmdList.Count - m ];
                        n = CmdList.Count - m;
                    }
                    MyTextBox.SelectionStart = MyTextBox.Text.Length;
                }

            }

            //Dowm
            if (e.KeyStates == Keyboard.GetKeyStates(Key.Down))
            {
                n++;
                e.Handled = true;
                var a = MyTextBox.Text;
                if (a.EndsWith(">"))
                {
                    if (CmdList.Count > 0 && (n - 1 < CmdList.Count))
                    {
                        MyTextBox.Text += CmdList[n - 1];
                        m = CmdList.Count - n;
                    }
                    MyTextBox.SelectionStart = MyTextBox.Text.Length;
                }
                else
                {
                    MyTextBox.Text = a.Remove(a.LastIndexOf(">")) + ">";
                    if (CmdList.Count > 0 && (n - 1 < CmdList.Count))
                    {
                        MyTextBox.Text += CmdList[n - 1];
                        m = CmdList.Count - n;
                    }
                    MyTextBox.SelectionStart = MyTextBox.Text.Length;
                }
            }

        }

        private bool VerifyCmd(string cmd)
        {
            bool flag = false;
            var str = cmd.Split(' ');
            if (str.Length > 0)
            {
                try
                {
                    if (str[0].ToLower().Contains("set"))//设置
                    {
                        var buf = str[1].ToLower().Split('-');
                        switch (buf[0])
                        {
                            case "v":
                                SetValue("v", Convert.ToInt32(buf[1]), Convert.ToInt32(str[2]));
                                break;

                            case "c":
                                SetValue("c", Convert.ToInt32(buf[1]), Convert.ToInt32(str[2]));
                                break;

                            case "t":
                                SetValue("t", Convert.ToInt32(buf[1]), Convert.ToInt32(str[2]));
                                break;

                            default:
                                break;
                        }
                        flag = true;
                    }
                    else if (str[0].ToLower().Contains("get"))//获取
                    {
                        var buf = str[1].ToLower().Split('-');
                        switch (buf[0])
                        {
                            case "v":
                                GetValue("v", Convert.ToInt32(buf[1]));
                                break;

                            case "c":
                                GetValue("c", Convert.ToInt32(buf[1]));
                                break;

                            case "t":
                                GetValue("t", Convert.ToInt32(buf[1]));
                                break;

                            default:
                                break;
                        }
                        flag = true;
                    }
                    else
                    {
                        flag = false;
                    }
                }
                catch (Exception ex)
                {
                    MyTextBox.Text += "\n" + ex.ToString() + "\n\r>";
                }
            }
            return flag;
        }

        private bool SetValue(string type,int Num,int Value)
        {
            MessageBox.Show($"走通讯协议 Set {type}-{Num} {Value}");
            //MyTextBox.Text += "\n" + $"{ DateTime.Now:yyyy - MM - dd HH: mm: ss}:" + $"Start \"{Cmd}\" Command is ok!\n\r>";
            return true;
        }

        private bool GetValue(string type, int Num)
        {
            MessageBox.Show($"走通讯协议 Set {type}-{Num}");
            //MyTextBox.Text += "\n" + $"{ DateTime.Now:yyyy - MM - dd HH: mm: ss}:" + $"Start \"{Cmd}\" Command is ok!\n\r>";
            return true;
        }
    }
}

进入终端界面:
在这里插入图片描述
终端命令都是以“>"来开头

成功运行后的界面:
在这里插入图片描述
完善:
TextBox控件属性增加:

            InputMethod.IsInputMethodEnabled="False"        
            PreviewTextInput="TextBox_PreviewTextInput"

InputMethod.IsInputMethodEnabled=“False” 是禁止输入法;PreviewTextInput="TextBox_PreviewTextInput"是对输入进行限制,使用正则表达式限制

        private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Regex re = new Regex(@"[^\u4e00-\u9fa5]");//限制中文字符

            e.Handled = !re.IsMatch(e.Text);
        }

后台需要实现的功能可以在VerifyCmd函数中添加。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hlpinghcg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值