自定义指令控件

模拟CMD命令窗体

定义一个继承TextBox的控件类

1:拥有自定义命令开头标识(如:>> )可自行调整为CMD等
2:接收回传信息自动换行并加上命令开头标识
3:可以通过上下键翻指令
4:回车发送指令
5:可以复杂粘贴指令
6:可以监听组合键,实现组合键执行特定指令操作(如:Ctrl+C清除输出记录)

    public class CommandTextControl : TextBox
    {
        #region 常量
        const string topLable = ">>";
        #endregion
        #region 属性值
        private int ItemIndex = 0;//命令下标索引
        private int cmdtextlineNum;
        /// <summary>
        /// 当前可以输入命令的行号
        /// </summary>
        public int MycmdtextlineNum
        {
            get => cmdtextlineNum;
            set
            {
                value = value < 0 ? value++ : value;
                cmdtextlineNum = value;
            }
        }
        /// <summary>
        /// 默认命令集合
        /// </summary>
        private List<string> DefaultCommandLiat = new List<string>
        { "CHDHelp","CMDLogOFF","CMDNormal"};
        /// <summary>
        /// 发送命令集合
        /// </summary>
        private List<string> SendCommandLiat = new List<string> { };
        private string commandStr;
        /// <summary>
        /// 发送指令
        /// </summary>
        public string CommandStr 
        {
            get => commandStr;
            set 
            {
                commandStr= value.Replace(topLable,"");
            }
        }
        #endregion
        public CommandTextControl()
        {
            this.Text += topLable;
            this.PreviewKeyDown += new KeyEventHandler(ConsoleTextBox_KeyDown);
            this.TextChanged += CMD_Changed;
        }
        #region 公有方法
        private void ConsoleTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            string AdhesivePlate = this.SelectedText;
            GetLineNum();
            if (e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Control) && e.Key == Key.C)
            {
                if (!string.IsNullOrEmpty(AdhesivePlate))
                {
                    Clipboard.SetDataObject(AdhesivePlate);
                }
                else
                {
                    CommandStr = DefaultCommandLiat.Last();
                    SendCommand();
                }
            }
            switch (e.Key)
            {
                case Key.Up:
                    OverRecored(true);
                    e.Handled = true;
                    break;
                case Key.Down:
                    OverRecored(false);
                    e.Handled = true;
                    break;
                case Key.Left:
                case Key.Right:
                case Key.Back:
                    LR_AND_ReMove(e);
                    break;
                case Key.Enter:
                    CommandStr = lines.Count>0?lines[MycmdtextlineNum - 1]:"";
                    SendCommand();
                    break;
                default:
                    if (!string.IsNullOrEmpty(AdhesivePlate))
                    {
                        return;
                    }
                    break;
            }
        }

        #endregion
        #region 私有方法
        StringCollection lines = new StringCollection();
        /// <summary>
        /// 获取总行数 
        /// </summary>
        /// <returns></returns>
        private StringCollection GetLineNum()
        {
            lines.Clear();
            for (int line = 0; line < MycmdtextlineNum; line++)
                lines.Add(this.GetLineText(line));
            return lines;
        }
        /// <summary>
        /// 新增命令输入行
        /// </summary>
        /// <param name="comm">命令内容可空</param>
        private void AddOneLine(string comm=null) 
        {
            this.Text += "\r\n" + topLable+ comm;
            this.SelectionStart = this.Text.Length;
        }
        /// <summary>
        /// 输出命令反馈内容
        /// </summary>
        /// <param name="outvalue">反馈内容</param>
        private void AddLogOutput(string outvalue)
        { 
            this.Text += "\r\n" + outvalue;
            AddOneLine();
            this.SelectionStart = this.Text.Length;
        }
        /// <summary>
        /// 发送指令
        /// </summary>
        private void SendCommand()
        {
            if (CommandStr.ToLower().Equals("cls"))
            {
                Clear();
                this.Text += topLable;
                this.SelectionStart = this.Text.Length;
                return;
            }
            if (string.IsNullOrEmpty(CommandStr))
            {
                return;
            }
            if (SendCommandLiat.Count>0)
            {
                string obj= SendCommandLiat.Last();
                if (obj!= CommandStr)
                {
                    SendCommandLiat.Add(CommandStr);
                }
            }
            else
            {
                SendCommandLiat.Add(CommandStr);
            }
            ItemIndex = SendCommandLiat.Count - 1;
            AddLogOutput(string.Format("发送执行》》》{0}", CommandStr));
        }
        /// <summary>
        /// 翻阅指令记录
        /// </summary>
        /// <param name="isUp"></param>
        private void OverRecored(bool isUp)
        {
            if (SendCommandLiat.Count > 0)
            {
                string[] sArray = this.Text.Split(new char[2] { '\r', '\n' });
                if (isUp)
                {
                    ItemIndex = ItemIndex >= 1 ? (ItemIndex - 1) : 0;
                    CommandStr = SendCommandLiat[ItemIndex];
                }
                else
                {
                    ItemIndex = ItemIndex < (SendCommandLiat.Count - 1) ? ItemIndex + 1 : ItemIndex;
                    CommandStr = SendCommandLiat[ItemIndex];
                }
                if (sArray.Last()== topLable || sArray.Last().Contains(topLable))
                {
                    string oldvalues= this.Text;
                    string newvalues= oldvalues.Remove(oldvalues.Length - sArray.Last().Length);

                    this.Dispatcher.Invoke(new Action((delegate {
                        this.Text="";
                        this.Text += newvalues + topLable + CommandStr;
                    })));
                    this.SelectionStart = this.Text.Length;
                }
                else
                {

                }
            }
        }
        /// <summary>
        /// 左右移动光标
        /// </summary>
        private void LR_AND_ReMove(KeyEventArgs e)
        {
            //获取光标所在行
            int CurrentLineNumber = GetLineIndexFromCharacterIndex(this.SelectionStart);
            //光标所在行第一个字符偏移量
            int lineFristCharOffset = this.GetCharacterIndexFromLineIndex(CurrentLineNumber);
            //当前光标偏移量
            int currentCharOffset =e.Key==Key.Left?this.SelectionStart-1:this.SelectionStart+1;
            //计算当前行的光标的偏移量
            int spanHeadLength = currentCharOffset - lineFristCharOffset;

           if (CurrentLineNumber + 1 != MycmdtextlineNum)
            {
                this.SelectionStart = this.Text.Length;
                e.Handled = true;
                return;
            }
            else
            {
                if (spanHeadLength >= topLable.Length)
                {
                    if (e.Key == Key.Back)
                    {
                        if (spanHeadLength == topLable.Length+1)
                        {
                            e.Handled = true;
                            return;
                        }
                    }
                    return;
                }
                else
                {
                    e.Handled = true;
                    return;
                }
            }
        }
        private void CMD_Changed(object sender, TextChangedEventArgs e)
        {
            MycmdtextlineNum = this.LineCount;
        }
        #endregion
    }

界面引用该控件

<Window x:Class="NewLayout.CMD_Window"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:Com="clr-namespace:NewLayout"
        mc:Ignorable="d"
        Title="CMD_Window" Height="450" Width="800">
    <Com:CommandTextControl Foreground="White" Background="Black"/>
</Window>

效果演示

回车发送指令以及上下翻指令记录
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值