[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 481
  • Last Modified:

Can I stop DoubleClick from firing an event in another Window?

This is driving me crazy.

I have a number of labels in Window1. Clicking a specific label correctly causes Window2, which has some buttons on it,  to be brought to the front.

If my user double-clicks on the label in Window1 and the ultimate position of one of the buttons in Window2 is in the same location as the label in Window1, the button fires. This is not desirable!

I can't just handle the double-click event in Window1, because that's not where the event shows up. I get the MouseClick event in Window1 which puts Window2 in place and then the event in Window2 fires.

Does anyone know how to control this?
0
AIBMass
Asked:
AIBMass
  • 6
  • 5
  • 2
2 Solutions
 
CodeCruiserCommented:
If first click shows the window and second click clicks the button on window, I don't think you can do much other than may show window2 at a location away from current mouse position.
0
 
AIBMassAuthor Commented:
Thanks for the thought. This doesn't help because the second event of the double-click is in the second window - having disabled the label in Window1 is no longer relevant.
0
 
CodeCruiserCommented:
I realized that hence you need to reread the comment!
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I can't think of any elegant ways to handle it...

Your options are:
(1) Train your users not to double click.
(2) Use a Timer() on Window2 so that any clicks within the first xxx milliseconds of it being displayed are ignored.  This could be done with a boolean flag and a hard-coded check in all the button click events.
(3) Lower level #2: Use IMessageFilter to literally consume any WM_LBUTTONDOWN messages intended for your application that occur within xxx milliseconds of the last WM_LBUTTONDOWN message.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Below is an example of #3:
Public Class Form1

    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Application.AddMessageFilter(New DoubleClickKiller)
    End Sub

    Private Sub Label1_Click(sender As System.Object, e As System.EventArgs) Handles Label1.Click
        Dim f2 As New Form2
        f2.StartPosition = FormStartPosition.Manual
        f2.Location = Me.Location
        f2.Show()
    End Sub

End Class

Public Class DoubleClickKiller
    Implements IMessageFilter

    Private Const WM_LBUTTONDOWN = &H201
    Private IgnoreWindowInMilliseconds As Integer = SystemInformation.DoubleClickTime ' <-- use the default, or specify your own time
    Private Last_WM_LBUTTONDOWN As DateTime = DateTime.MinValue

    Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
        Select Case m.Msg
            Case WM_LBUTTONDOWN
                Dim CurrentDateTime = DateTime.Now
                If Last_WM_LBUTTONDOWN <> DateTime.MinValue Then
                    If CurrentDateTime.Subtract(Last_WM_LBUTTONDOWN).TotalMilliseconds <= IgnoreWindowInMilliseconds Then
                        Return True ' Consume the click so it doesn't propagate to the application
                    End If
                End If
                Last_WM_LBUTTONDOWN = CurrentDateTime
        End Select
        Return False ' Allow valid messages to be processed normally
    End Function

End Class

Open in new window


*If you need double clicks to be valid elsewhere in the application then you'll need to modify the filter so you can notify it when to ignore clicks; and also allow it to reset itself after the lockout period.
0
 
AIBMassAuthor Commented:
Let me see. First, an apology to CodeCruiser. Indeed I was responding to some other message rather than the one that was written.

CodeCruiser's suggestion to locate Window2 away from the MouseClick would certainly work. I see the following problems: 1. Because any of the windows in the application can be moved around the placement logic is not simple and 2. We are permanently subjecting some components of the application (Window1) to know about the UI of other components (Window2) and this is highly undesirable. Still, it will have merit in some simple cases.

Idle_Mind has two excellent suggestions. The DoubleClickKiller class works perfectly as supplied. I am strongly considering this method as I don't think the application has any actual call for a DoubleClick. However, this is a bit esoteric for many and that's a disadvantage.

Finally, I am considering a variation of Idle_Mind's second suggestion. I set a variable to the current time when the form is loaded and then provider a function for the Click events to call to verify that the difference between the form load time and the click time exceeds the double click time. This code should be easily understandable even if the motivation for having it is not.

Thanks to both CodeCruiser and Idle_Mind.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
There's no good solution to this problem.  =\

While definitely esoteric, the DoubleClickKiller() solution doesn't require changes to every button handler in the application.  You just load it with the one line and you're done!

       Application.AddMessageFilter(New DoubleClickKiller)

The other route will require changes all over the place and increases the chances that you'll make a mistake, or forget to add that additional code down the line if the UI changes.

Good luck!
0
 
AIBMassAuthor Commented:
Post Mortem: Before implementing the DoubleClickKiller, I am anticipating a problem. Think of the label(s) on Form1 as being Order Numbers and that Form2 is the detail window for orders.

Depending on the size of the order and other issues, it may take anywhere from .25 second to 4 or 5 seconds for Form2 to appear. Thus I fear the second mousedown may be a few seconds, rather than some milliseconds, after the first and thus blow the whole scheme.

I guess I'll have to find out.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Keep us posted...I'm curious.
0
 
AIBMassAuthor Commented:
Real life experience with DoubleClickKiller.

Setting the interval between the MouseButtonDown events to 1 second is too fast for Form2 to load. Setting it to 3 seconds works fine in this specific regard, but I am concerned that this is way too long for other parts of the application.

I will turn now to some variation of the timers.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I would look at the loading code in Form2.  Can that be threaded with the BackgroundWorker()?...
0
 
AIBMassAuthor Commented:
I am going with setting a timestamp when the form has been loaded and filled with data and insisting that the button click be more than 250 milliseconds from that time.

This was way too difficult.

It seems like an underlying Windows flaw that a UI event from one Window can show up in another Window.  It just shouldn't be so :(
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Well...part of the problem is that all user interaction gets processed in the main UI thread.  If you thread the length record loading work, then the main UI thread can be free to process that second pending click, and consequently discard it.  If all the work remains in the main UI thread and takes longer than one second to load, then the pending messages also sit there for one second waiting to be processed.  If the loading takes even longer then can end up with an un-responsive UI, or a "white out" where the main form being displayed doesn't repaint while the secondary form is still loading.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 6
  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now