5

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.

Sergii Zhevzhyk
  • 4,074
  • 22
  • 28
  • 1
    You could use a timer and check if the mouse button is down then the code from `frmMain_MouseHover` should be executed. You could check this [answer](http://stackoverflow.com/questions/8159534/net-how-to-check-if-the-mouse-is-in-a-control) – Sergii Zhevzhyk Dec 09 '15 at 21:45
  • Awesome solution! Thinkin outside the box! Tysm! – Walter Bishop Dec 09 '15 at 23:12

2 Answers2

3

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

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;
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Tysm for the suggestion, going to play around with these events and see if this would work better. Always thought these events were only for dragging files onto the form. – Walter Bishop Dec 09 '15 at 23:12
  • 1
    You are welcome :) let me know if you have any question about the answer or if you could solve the problem :) – Reza Aghaei Dec 09 '15 at 23:15
  • 1
    By the way, when a post answers your question, you can kindly accept it by click on check mark and vote for it using up arrow :) [Accepting answers, How does it work?](http://meta.stackexchange.com/a/5235/308647) You can only accept one answer, but you can vote up as many answers you find helpful, including the accepted one. – Reza Aghaei Dec 10 '15 at 09:46
-1

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.

Anthony Hart
  • 157
  • 7
  • 1
    How exactly is this not an answer? He's using the wrong events. Don't go downvoting people just because you don't know how to fix his problem. Using a timer is a stupid and needless way of solving this solution when he can get the exact results he is looking for by using the drag events instead of click. . . . – Anthony Hart Dec 09 '15 at 21:56
  • 3
    @AnthonyHart Your answer is technically correct +1 to your answer. But it's better to add more details to answer, like I did :) Hope you find the answer helpful :) – Reza Aghaei Dec 09 '15 at 22:23
  • 2
    You cannot post a bunch of links without any explanation. At least, you should write that the events he used doesn't fit in this situation and he needs to use something else (specify the events and how to use them). It's important to have links in the answer but they can change so it makes sence to cite them in your answer. My comment may be wrong that's why it's a comment but not an answer. I totally agree that using of a timer is not the best approach. Please improve your answer and people will upvote it. – Sergii Zhevzhyk Dec 09 '15 at 22:23