【问题标题】:MouseHover not firing when mouse is down鼠标按下时鼠标悬停不触发
【发布时间】:2016-03-15 08:25:27
【问题描述】:

我正在开发一个 WordSearch 拼图程序(也称为 WordFind),您必须在其中找到大量字母中的某些单词。我正在使用 C# WinForms。

我的问题是当我想单击并按住 1 个字母 (Label),然后拖动到其他字母以更改它们的 ForeColor。我试过谷歌搜索,但无济于事。

这是我所拥有的:

foreach (Letter a in game.GetLetters())
{
     this.Controls.Add(a);
     a.MouseDown += (s, e2) =>
     {
         isDown = true;
         a.ForeColor = Color.Yellow;
     };
     a.MouseUp += (s, e2) =>
     {
         isDown = false;
     };
     a.MouseHover += (s, e2) =>
     {
         if (isDown)
             a.ForeColor = Color.Yellow;
     };
}

但是,除非没有按住鼠标,否则 MouseHover 事件永远不会触发。用MouseEnter 交换MouseHover 也没有运气。所以,我保留了 MouseDownMouseUp 事件,并尝试在表单本身中使用 MouseHover:

private void frmMain_MouseHover(object sender, MouseEventArgs e)
{
    if (isDown)
    {
        foreach (Letter l in game.GetLetters())
           if (l.ClientRectangle.Contains(l.PointToClient(Control.MousePosition)))
               l.ForeColor = Color.Purple;
    }
}

这个事件也没有触发,我不知道为什么它没有触发以及一些替代解决方案是什么。任何建议表示赞赏。

【问题讨论】:

  • 您可以使用计时器并检查鼠标按钮是否按下,然后应该执行来自frmMain_MouseHover 的代码。你可以检查这个answer
  • 很棒的解决方案!跳出框框思考!太棒了!

标签: c# winforms mousehover


【解决方案1】:

您可以使用拖放事件。

  1. 为每个作为放置目标的控件设置AllowDrop 属性。
  2. 为每个从它开始拖动的控件处理MouseDown事件,并在该控件的处理程序调用DoDragDrop事件中设置要拖动的数据。
  3. 处理每个拖动目标的DragEnetr事件并设置e.Effect来确定是否允许拖放。这是您可以检查是否允许放置的地方,将背面颜色更改为您想要的颜色。
  4. 处理 DragLeave 以重置背景颜色。
  5. Hanlde DragDrop 并使用 GetData 方法 if e.Data 获取数据并在放置时执行操作。

走过

示例

我有 3 个按钮,按钮 1 和按钮 2,按钮 3 和按钮 2 是放置的目标。在下面的代码中,我将检查将放在按钮 2 上的文本是否是按钮 1 的文本,我将按钮 2 的背景颜色更改为绿色,否则为红色。另外,如果您将鼠标拖出button2,我会将背景颜色设置为默认值。如果你放弃,我会更改button2的文本并设置button1的文本:

//Start drag for button 2
private void button1_MouseDown(object sender, MouseEventArgs e)
{
    this.button1.DoDragDrop(this.button1.Text, DragDropEffects.Copy);
}

//Start drag for button 3
private void button3_MouseDown(object sender, MouseEventArgs e)
{
    this.button3.DoDragDrop(this.button3.Text, DragDropEffects.Copy);
}

//Check if drop is allowed and change back color
private void button2_DragEnter(object sender, DragEventArgs e)
{
    if(e.Data.GetData(DataFormats.Text).ToString()== button1.Text)
    {
        e.Effect = DragDropEffects.Copy;
        this.button2.BackColor = Color.Green;
    }
    else
    {
        e.Effect = DragDropEffects.None;
        this.button2.BackColor = Color.Red;
    }
}

//Perform drop actions
private void button2_DragDrop(object sender, DragEventArgs e)
{
    this.button2.Text = e.Data.GetData(DataFormats.Text).ToString();
}

//Reset back color here
private void button2_DragLeave(object sender, EventArgs e)
{
    this.button2.BackColor = SystemColors.Control;
}

【讨论】:

  • Tysm 的建议,去玩这些事件,看看这是否会更好。一直认为这些事件只是为了将文件拖到表单上。
  • 不客气 :) 如果您对答案有任何疑问或是否可以解决问题,请告诉我 :)
  • 顺便说一句,当一个帖子回答你的问题时,你可以通过点击复选标记接受它并使用向上箭头投票:) Accepting answers, How does it work?你只能接受一个答案,但你可以投票给您认为有帮助的答案,包括被接受的答案。
【解决方案2】:

您正在寻找各种拖动事件:

https://msdn.microsoft.com/en-us/library/system.windows.forms.control.dragenter(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/system.windows.forms.control.dragover(v=vs.110).aspx

等等……

您遇到的问题是您使用错误的事件来完成您想要完成的任务。

【讨论】:

  • 这到底是怎么回事?他使用了错误的事件。不要仅仅因为你不知道如何解决他的问题而对别人投反对票。当他可以通过使用拖动事件而不是单击来获得他正在寻找的确切结果时,使用计时器是解决此解决方案的一种愚蠢且不必要的方法。 . . .
  • @AnthonyHart 您的回答在技术上是正确的 +1 对您的回答。但是最好像我一样添加更多详细信息来回答:) 希望你的答案对你有帮助:)
  • 你不能在没有任何解释的情况下发布一堆链接。至少,您应该写下他使用的事件不适合这种情况,他需要使用其他东西(指定事件以及如何使用它们)。在答案中包含链接很重要,但它们可以更改,因此在您的答案中引用它们是有意义的。我的评论可能是错误的,这就是为什么它是评论而不是答案。我完全同意使用计时器不是最好的方法。请改进您的答案,人们会支持它。
猜你喜欢
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多