【问题标题】:C# keyboard event handler rectangleC# 键盘事件处理程序矩形
【发布时间】:2016-05-15 22:25:32
【问题描述】:

我是 C# 新手,并尝试制作一个键盘事件。它应该在按下 W、A、S 或 D 键时显示。首先,我的计划是显示一些图片框,然后在按下右键时更改图片。

但后来我搜索了互联网并在 Java http://docs.oracle.com/javase/8/javafx/sample-apps/KeyboardExample.zip 中找到了类似的东西 它看起来像这样:

据我所知,代码正在绘制一个带有一些字母的矩形。我查看了 msdn 并找到了一个绘制矩形的示例: https://msdn.microsoft.com/de-de/library/sx8yykw8(v=vs.110).aspx

不幸的是,我卡在了图纸上。通常我使用工具箱向表单添加内容。然后我双击它并将我的代码写在大括号内。但是工具箱里没有“矩形”,所以不知道怎么添加。

这是我目前的代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        //Stay always on top
        this.TopMost = true;
        //Does not work. Removes border but you can't move the window after this
        this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        //Can I delete this?            
    }

    private void Form1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (e.KeyChar >= 65 && e.KeyChar <= 122)
        {
            switch (e.KeyChar)
            {
                //If pressed w or W
                case (char)119:
                case (char)87:
                    Console.WriteLine(e.KeyChar);
                    break;
                //If pressed a or A
                case (char)97:
                case (char)65:
                    Console.WriteLine(e.KeyChar);
                    break;
                //If pressed s or S
                case (char)83:
                case (char)115:
                    Console.WriteLine(e.KeyChar);
                    break;
                //If pressed d or D
                case (char)100:
                case (char)68:
                    Console.WriteLine(e.KeyChar);
                    break;
                //Other keys
                default:
                    lblMessage.Text = "Key not supported";
                    //does not work
                    //timer1_Tick();
                    break;
            }
        }
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        lblMessage.Hide();
    }
}

这是我的表单现在的样子:

我目前还停留在的其他事情:

  • 如何从 Form1_KeyPress 调用计时器以在几秒钟后隐藏 lblMessage?

  • 移除边框而不失去移动窗口的能力(例如this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

编辑:我将代码更改为最新的工作状态。

【问题讨论】:

    标签: c# events drawing


    【解决方案1】:

    欢迎来到 Windows 桌面编程的世界!

    这里有两个选择;你可以:

    1. 使用设计视图将组件添加到 WASD 表单(因为那里有 W、A、S、D 框,看起来您已经添加了它们)和 Form1_KeyPress() 处理程序中,只需更新属性的盒子。这可以像下面这样简单,只需确保将其更改为正确的组件名称即可:

      //If pressed w or W
      case (char)119:
      case (char)87:
              Console.WriteLine(e.KeyChar);
              button1.BackColor = Color.Red;//Highlight W
              button2.BackColor = Color.Empty;//Ignore A
              button3.BackColor = Color.Empty;//Ignore S
              button3.BackColor = Color.Empty;//Ignore D
              break;
      
    2. 覆盖表单的 OnDraw() 处理程序并直接在屏幕上绘制框。这更难,但会给你更多的力量。

    关闭标签很容易。在您的 Form1_Load() 处理程序中,确保设置 timer1 的超时属性:

    private void Form1_Load(object sender, EventArgs e)
    {
        timer1.Interval = 5000;//In ms = thousandths-of-a-second
    }
    

    在 Form1_KeyPress() 处理程序中打开计时器:

    private void Form1_KeyPress(object sender, KeyPressEventArgs e)
    {
        ...
        lblMessage.Enabled = true;
        timer1.Start();
    }
    

    做你的工作并关闭 timer1_Tick() 处理程序中的计时器:

    private void timer1_Tick(object sender, EventArgs e)
    {
        lblMessage.Enabled = false;
        timer1.Stop();
    }
    

    【讨论】:

    • 我尝试使用pictureBox1.BackColor = Color.Red; 更改颜色,但它不起作用。我想是因为它只是我用图片框导入的一张图片?
    • 第二个选项又是如何工作的?更多的权力是什么意思?编码会比图片更好吗?
    • 感谢您对计时器的帮助。现在看起来很容易。 :)
    【解决方案2】:

    以下是我快速整理的内容:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WASD_Keyboard
    {
        public partial class Form1 : Form
        {
            private PictureBox pictureBox1 = new PictureBox();
            private bool wPressed = false;
            private bool aPressed = false;
            private bool sPressed = false;
            private bool dPressed = false;
            private Timer timer = new Timer();
    
            public Form1()
            {
                InitializeComponent();
                //Stay always on top
                this.TopMost = true;
                //Does not work. Removes border but you can't move the window after this
                this.FormBorderStyle = FormBorderStyle.None;
    
                timer.Interval = 3000;
                //this is an event binding
                timer.Tick += timer1_Tick;
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                // Dock the PictureBox to the form and set its background to white.
                pictureBox1.Dock = DockStyle.Fill;
                pictureBox1.BackColor = Color.White;
                pictureBox1.Paint += DrawRectangleRectangle;
                // Add the PictureBox control to the Form.
                this.Controls.Add(pictureBox1);
            }
    
            private void Form1_KeyPress(object sender, KeyPressEventArgs e)
            {
                // reversed logic to stop nesting
                if (e.KeyChar < 65 || e.KeyChar > 122) return;
    
                wPressed = false;
                aPressed = false;
                sPressed = false;
                dPressed = false;
                //this should really be multiple if statement so it can do more than one key
                //If pressed w or W
                if (e.KeyChar == (char) 119 || e.KeyChar == (char) 87) {
                    wPressed = true;
                    Console.WriteLine(e.KeyChar);
                }
    
                //If pressed a or A
                if (e.KeyChar == (char) 97 || e.KeyChar == (char) 65) {
                    aPressed = true;
                    Console.WriteLine(e.KeyChar);
                }
    
                //If pressed s or S
                if (e.KeyChar == (char) 83 || e.KeyChar == (char) 115) {
                    sPressed = true;
                    Console.WriteLine(e.KeyChar);
                }
    
                //If pressed d or D
                if (e.KeyChar == (char) 100 || e.KeyChar == (char) 68) {
                    dPressed = true;
                    Console.WriteLine(e.KeyChar);
                }
    
                if (!wPressed && !aPressed && !sPressed && !dPressed) {
                    //Something goes wrong
                    lblMessage.Text = "Key not supported";
                    return;
                }
    
                pictureBox1.Refresh();
                // in older .net if you didn't do both you ran into multiple issues
                timer.Enabled = true;
                timer.Start();
            }
    
            public void DrawRectangleRectangle(object sender, PaintEventArgs e)
            {
                DrawRectangle(e, new Point(40, 10), new Size(20, 20), 'W', wPressed ? Color.Red : Color.White);
                DrawRectangle(e, new Point(10, 40), new Size(20, 20), 'A', aPressed ? Color.Red : Color.White);
                DrawRectangle(e, new Point(40, 40), new Size(20, 20), 'S', sPressed ? Color.Red : Color.White);
                DrawRectangle(e, new Point(70, 40), new Size(20, 20), 'D', dPressed ? Color.Red : Color.White);
            }
    
            public void DrawRectangle(PaintEventArgs e, Point p, Size s, char letter, Color c)
            {
                // Create pen.
                var blackPen = new Pen(Color.Black, 3);
                var brush = new SolidBrush(c);
                // Create rectangle.
                var rect = new Rectangle(p, s);
    
                // Draw rectangle to screen.
                e.Graphics.DrawRectangle(blackPen, rect);
                e.Graphics.FillRectangle(brush, rect);
                e.Graphics.DrawString(letter.ToString(), new Font(FontFamily.GenericSerif, 12), Brushes.Blue, rect);
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                wPressed = false;
                aPressed = false;
                sPressed = false;
                dPressed = false;
    
                timer.Enabled = false;
                timer.Stop();
                pictureBox1.Refresh();
            }
        }
    }
    

    注意:这是高度异步的,但不使用任何锁定...

    【讨论】:

    • 这个timer.Tick += timer1_Tick;在做什么?我只知道+=的意思是var = var + a;
    • timer.Enabled = false;timer.Stop(); 不一样吗?
    • 为什么if (e.KeyChar &lt; 65 || e.KeyChar &gt; 122) return; 有返回?原因还是错字?
    • 哦,我知道您已更改为 AND 为 OR,这确实是一个有趣的解决方案。
    • 效果很好!我只需将第 81 行和第 82 行的 timer 更改为 timer1。感谢您的大力帮助。
    猜你喜欢
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多