C# 在鼠标周围创建按钮

C# create buttons around mouse

我想让4个按钮在指针延迟3秒时显示在指针周围。如果我通过悬停 4 个按钮之一来激活,所有按钮都将被隐藏。

Like this:

Mouse selection

我假设您使用的是 WinForms。

一个问题是你的图片实际显示的不是矩形按钮。这是另一个困难,但我想把它限制在你的问题上。因此,您需要能够做一些事情。

  1. 获取鼠标位置
  2. 获取一个在 3 秒内没有鼠标移动时调用的方法
  3. 动态创建按钮
  4. 设置按钮的位置。

让我们一步步来:

1.获取鼠标位置

因此您必须处理 MouseMove 事件。因此,您 select 您的表单,转到属性(按 F4),select 事件选项卡(闪电图标),然后双击 MouseMove[=98= 右侧的字段].这将在您的代码后面创建 Form1_MouseMove 方法。在这种方法中,您可以使用 e.Location;.

获取鼠标位置

到这里为止我们的方法如下所示:

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    var location = e.Location;
}

2。获取当 3 秒没有鼠标移动时调用的方法

因此我想使用计时器。为此,您再次切换到设计器(按 F7),打开工具箱 (CTRL + ALT + X) 并将 Timer 项拖到您的表单中。 Select 新创建的计时器(在你的表单下可见),再次切换到属性选项卡,select 属性(闪电左侧的图标),双击[=右侧的字段77=]Enabled 将其设置为 true,再次切换到事件选项卡并双击 Tick 右侧的字段。那里的方法将每 100 毫秒调用一次。然后您将添加一个名为 _timePassedSinceLastMove 的字段。每次调用 tick 方法时都会增加它,并在调用 Form1_MouseMove 时再次将其设置为 0。在 timer1_Tick 方法中,您将检查 _timePassedSinceLastMove 字段是否已超过 30,如果是,您将调用每 3 秒调用一次的方法。实际上,我们仍然需要检查您的鼠标位置是否真的与旧鼠标位置不同,因为 winForms 在这种情况下有点过于敏感。因此,我们添加一个包含旧位置的字段并将其与新位置进行比较。您的 class 现在应该看起来像这样:

public partial class Form1 : Form
{
    private Point _oldMousePosition;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        var location = e.Location;
        if (_oldMousePosition == location)
            return;
        _oldMousePosition = location;
        _timePassedSinceLastMove = 0;
    }

    private int _timePassedSinceLastMove;

    private void timer1_Tick(object sender, EventArgs e)
    {
        _timePassedSinceLastMove++;
        if (_timePassedSinceLastMove > 30)
        {
            MouseNotMove3Seconds();
            _timePassedSinceLastMove = 0;
        }
    }

    private void MouseNotMove3Seconds()
    {
    }
}

3。动态创建按钮

我认为此任务是所有任务中最简单的。我认为最好用一个例子来解释:

var button = new Button();
Controls.Add(button);

我们只需创建一个新按钮并将其添加到我们表单的控件中(这也在后面的代码中执行)。如果我们想在鼠标不移动时添加 4 个按钮,我们只需这样做:

private void MouseNotMove3Seconds()
{
    var button1 = new Button();
    Controls.Add(button1);
    var button2 = new Button();
    Controls.Add(button2);
    var button3 = new Button();
    Controls.Add(button3);
    var button4 = new Button();
    Controls.Add(button4);
}

4.设置按钮的位置

设置按钮的位置也不难:

var button1 = new Button();
button1.Location = new Point(0, 0);

我们也可以使用对象初始化器将其写得更漂亮:

var button1 = new Button {Location = new Point(0, 0)};

但现在我们不希望所有按钮都位于位置 0,0,而是围绕我们的光标。所以我们会做类似的事情(位置总是在左上角):

private void MouseNotMove3Seconds()
{
    var button1 = new Button {Location = new Point(_oldMousePosition.X + Cursor.Size.Width, _oldMousePosition.Y)};
    Controls.Add(button1);
    var button2 = new Button {Location = new Point(_oldMousePosition.X - button1.Width / 2, _oldMousePosition.Y + Cursor.Size.Height)}; //I cheated a little bit here, but as the buttons are all the same...
    Controls.Add(button2);
    var button3 = new Button {Location = new Point(_oldMousePosition.X - (int)(button1.Width * 1.5), _oldMousePosition.Y)};
    Controls.Add(button3);
    var button4 = new Button {Location = new Point(_oldMousePosition.X - button1.Width / 2, _oldMousePosition.Y - (int)(button1.Height * 1.5))};
    Controls.Add(button4);
}

你现在说你想在鼠标悬停时再次删除按钮。所以我们需要创建一个方法 ButtonHovered:

private void ButtonHovered(object sender, EventArgs e)
{
    Controls.Clear();
}

现在我们只是删除添加到表单中的所有组件(按钮)。当然,如果您的表单中有更多组件,您只需从组件中删除这四个按钮并保留其余部分。

虽然现在没有调用这个方法,因为我们没有处理按钮的悬停事件。因此我们必须稍微修改我们的 MouseNotMoved3Seconds 方法:

private void MouseNotMove3Seconds()
{
    var button1 = new Button {Location = new Point(_oldMousePosition.X + Cursor.Size.Width, _oldMousePosition.Y)};
    Controls.Add(button1);
    var button2 = new Button {Location = new Point(_oldMousePosition.X - button1.Width / 2, _oldMousePosition.Y + Cursor.Size.Height)}; //I cheated a little bit here, but as the buttons are all the same...
    Controls.Add(button2);
    var button3 = new Button {Location = new Point(_oldMousePosition.X - (int)(button1.Width * 1.5), _oldMousePosition.Y)};
    Controls.Add(button3);
    var button4 = new Button {Location = new Point(_oldMousePosition.X - button1.Width / 2, _oldMousePosition.Y - (int)(button1.Height * 1.5))};
    Controls.Add(button4);
    button1.MouseHover += ButtonHovered;
    button2.MouseHover += ButtonHovered;
    button3.MouseHover += ButtonHovered;
    button4.MouseHover += ButtonHovered;
}

现在我们将事件附加到 ButtonHovered 方法,只要用户将鼠标悬停在其中一个按钮上,就会调用该方法。

如果想知道是哪个按钮导致按钮消失,通过sender属性将导致事件触发的按钮交给ButtonHovered方法。

在你的图片中,你的按钮上也写有文字,所以让我们也这样做。因此,我们将在 MouseNotMove3Seconds 方法中更改对象初始值设定项中按钮的 Text 属性:

private void MouseNotMove3Seconds()
{
    var button1 = new Button
    {
        Location = new Point(_oldMousePosition.X + Cursor.Size.Width, _oldMousePosition.Y),
        Text = "B"
    };
    Controls.Add(button1);
    var button2 = new Button
    {
        Location = new Point(_oldMousePosition.X - button1.Width / 2, _oldMousePosition.Y + Cursor.Size.Height),//I cheated a little bit here, but as the buttons are all the same...
        Text = "C"
    }; 
    Controls.Add(button2);
    var button3 = new Button
    {
        Location = new Point(_oldMousePosition.X - (int)(button1.Width * 1.5), _oldMousePosition.Y),
        Text = "D"
    };
    Controls.Add(button3);
    var button4 = new Button
    {
        Location = new Point(_oldMousePosition.X - button1.Width / 2, _oldMousePosition.Y - (int)(button1.Height * 1.5)),
        Text = "A"
    };
    Controls.Add(button4);
    button1.MouseHover += ButtonHovered;
    button2.MouseHover += ButtonHovered;
    button3.MouseHover += ButtonHovered;
    button4.MouseHover += ButtonHovered;
}

虽然此解决方案看起来不像您的图片(那是因为按钮形状不同),但它应该可以帮助您解决问题。如果您的问题是形状不同的按钮,请提出一个新问题。

希望能帮到你。