MouseHover not firing when mouse is down

2019-06-21 20:19发布

问题:

I'm working on a WordSearch puzzle program (also called WordFind) where you have to find certain words in a mass of letters. I'm using C# WinForms.

My problem is when I want to click and hold 1 letter(Label), then drag over to other letters to change their ForeColor. I've tried googling but to no avail.

Here is what I have:

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

However, the MouseHover event never fires unless the mouse is not being held down. Also no luck swapping MouseHover with MouseEnter. So, I kept the MouseDown and MouseUp events and tried using MouseHover within the form itself:

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

This event does not fire either and I'm at a loss as to why it's not firing and what some alternative solutions are. Any advice is appreciated.

回答1:

You can use Drag and Drop events.

  1. Set AllowDrop property for each control that is target of drop.
  2. Handle MouseDown event for each control that drag starts with it and in the handler call DoDragDrop event of that control and set the data that you want to drag.
  3. Handle DragEnetr event of each target of drag and set e.Effect to determine if drop is allowed or not. Here is the place that you can check if drop is allowed, change the back color to your desired color.
  4. Handle DragLeave to reset the back color.
  5. Hanlde DragDrop and use GetData method if e.Data to get the data and perform the actions when drop.

walking through

  • Walkthrough: Performing a Drag-and-Drop Operation in Windows Forms

Example

I have 3 buttons, button1 and button2 and button3 and button2 is target of drop. In the below code, I'll check if the text that will drop on button 2, is the text of button1, I'll change the back color of button 2 to green, else to red. also if you take dragging mouse out of button2, I'll set the back color to default. If you drop, I'll change the text of button2 and will set the text of 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;
}


回答2:

You're looking for the various drag events:

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

etc...

The problem that you are running into is that you are using the wrong events for what you are trying to accomplish.