【问题标题】:C# create buttons around mouse [closed]C#在鼠标周围创建按钮[关闭]
【发布时间】:2017-04-16 12:42:49
【问题描述】:

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

像这样:

Mouse selection

【问题讨论】:

  • 很抱歉给您带来不便,我不知道如何创建这些按钮。
  • 您的目标是什么:Winforms、WPF、ASP..? 总是正确标记您的问题!

标签: c# cursor mouse


【解决方案1】:

我假设您使用的是 WinForms。

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

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

让我们一步一步来:

1.获取鼠标位置

因此,您必须处理 MouseMove 事件。因此,您选择您的表单,转到属性(按 F4),选择事件选项卡(闪电图标),然后从 MouseMove 双击进入该字段。这将在您的代码中创建 Form1_MouseMove 方法。在这种方法中,您可以使用e.Location; 获取鼠标位置。

到目前为止,我们的方法如下所示:

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

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

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

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();
}

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

这个方法现在没有被调用,因为我们没有处理按钮的 Hover 事件。因此我们必须稍微修改一下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;
}

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

希望能帮到你。

【讨论】:

  • 提前谢谢你,我希望你的帮助:)
  • @YingYoh 我错过了你的部分问题并编辑了我的答案以符合要求。
  • 非常感谢,这对我帮助很大。
猜你喜欢
  • 1970-01-01
  • 2015-01-23
  • 2017-07-05
  • 1970-01-01
  • 2019-02-07
  • 1970-01-01
  • 2012-09-20
  • 2015-01-14
  • 1970-01-01
相关资源
最近更新 更多