|
Timing doesn't enter into it. You can hold a Button down with the left mouse button as long as you want and it won't Click until MouseUp. Also you can press the left mouse button and then move the mouse away from the Button and the Button return to unpressed with no Click or MouseUp being triggered.
What I do is:
on MouseDown I store a reference to the control that triggered it
on MouseEnter or MouseLeave I clear the value (just in case)
on MouseUp I compare the control that triggered MouseUp with the control that triggered the MouseDown, and if they're the same I raise an event and clear the value
|
|
|
|
|
I think timespan is only a factor if you are distinguishing double-clicks.
I like what you are doing, though.
|
|
|
|
|
I seem to recall (from an hour ago) that MouseEventArgs contains info to help detect double-clicks.
|
|
|
|
|
Clicks returns the number of times that the control was clicked, but I'd have to do some work to determine if it returns the number of right clicks (unless we counted them) or whether the right-clicks were executed within the system parameters for recognizing a "double click."
|
|
|
|
|
I'm still chewing on this (and not about to throw it away). Just wondering... I can see how you might be doing this in an application, but are you writing controls based on this principle (which may require logical involvement *all* controls)?
|
|
|
|
|
No, I don't write my own controls.
I have a private MouseTrap field in my Form. Then any controls (like Buttons) for which I want to simulate right-clicks I use:
MouseTrap.Add ( button1 ) ;
Which adds the MouseTrap's methods as handlers for the Controls' MouseUp, MouseDown, MouseEnter, and MouseLeave events.
If a Control triggers a MouseDown followed by a MouseUp (with no MouseLeave or MouseEnter in between) then the MouseTrap raises its own MouseClick event.
I write a general MouseClick handler to figure out which Control fired the event, but I may be able to streamline that.
Anyway, this is just something I have been dreaming up for a few weeks and finally waded into today. It may be a while before I have something that's ready for prime time.
|
|
|
|
|
I'm pleased with my right mouse behavior, but I think your idea is quite cool for many purposes.
A suggestion crosses my mind. Manual registration of controls may be the way to go for some users, but you can also provide the option of automating the registration process -- performing the following process for instance based on the value of a boolean field:
After creating your form, run a process which iterates its Controls array and the Controls arrays of each control it encounters. In this cycle, register your delegate(s) to each control's Up/Down/Enter events as necessary, filtering for whatever classes of controls you intend to support. That should automatically wire your process -- and make your form the first automatic mouse trap!
|
|
|
|
|
I think you want the MouseUp event.
I just spent some time this afternoon working on making buttons and things "right clickable" too.
|
|
|
|
|
I probably won't revise all my old RightClick code, but I have to admit your suggestion is an intriguing approach -- more correct in regard to allowing (possibly) the operator to mouse out of the control before mouse up. But it's not what I'd want to do in terms of timely response. To get fancy, I would measure the time-span from right mouse-down. Otherwise, MouseUp is an interesting alternative we should probably consider for the given purposes.
|
|
|
|
|
That's why I wrote a class (MouseTrap) and added it to my derivation of Form. Now all my Forms will have this ability built in.
|
|
|
|
|
|
(But alas, POOR KATARIC!)
|
|
|
|
|
|
Yes. I think they needed a simple, straightforward way to detect right click!
|
|
|
|
|
"They" being Microsoft? Yes, it should be supported. The only reason I can think of not to is in case .net gets ported to Mac
|
|
|
|
|
Poor Kataric's head hurts.
But seriously, the FCL can't handle a right click the same way it handles a left click?
How come the button, even when no controls are present, depresses on a left click, but not on any other click, and would using mouseup provide the necessary depression animation?
|
|
|
|
|
You're thinking pretty clearly, if your head hurts.
The point should be this: Animation or whatever, you have to use the event required to trigger the animation or whatever. If you want/need to animate the down state of the button at mouse down, you'll have to handle that much with mouse down. If you want to trigger the right click at mouse down... the same applies. If you want to trigger it at mouse up... you'll have to use that event. To animate the up state (if you're animating the down), you'll have to use the appropriate events here as well. That may be MouseUp, exit, on focus change. You'll see which you have to use for what you want to do by taking a careful look at the control -- it furnishes the tools you *can* use to accomplish what you have or want to do. If it doesn't provide an event opportunity, you may be able to build one in, but the possibility of that too depends on having a driving event you can work with.
|
|
|
|
|
For example, the snippet I provided added a RighClick event to a button class, using the OnMouseDown event.
|
|
|
|
|
So the left click is just intrinsiclly written to animate on mouse down and mouse up?
|
|
|
|
|
Yes. I for one don't care about the animation, so my solution doesn't supply it either.
I suspect to have it you would need to write/derive your own Button that does the same (override the OnPaint method et al).
I won't bother, I hope the "next" version of .net has it built in, until then I'll simply have Buttons and whatever that kinda sorta respond to right-click, but don't depress.
|
|
|
|
|
That's right. The animation behavior can be added to the button class so that the button responds/animates to right mouse button behavior like it does the left, if, and only if, the button class allows you to invoke the down state. I build an extensive heirarchy of such button classes for the further purpose of supporting toggle behavior, which requires that you programmatically set a down state -- the same state you need to invoke to support your right click behavior.
I know it seems strange that the developers of the native FCL button class did not provide this type of functionality for you -- including a native right click. Sometimes there's a good underlying technical reason. In this case, I don't believe so. The fact that so many of us run into this issue and are obstructed from emulating all the desirable behavior in a practical way indeed supports our sentiments. The fact is (I adamantly believe), this is a perfect example of designers not doing the job the way the job needs to be done. But you can see how carried away they got with further adverse themes when you start getting involved in button renderers and all the further baggage thrown in. By the time you can get your brain around the basic, *undocumented* idea they had, you can write your own button class that even draws itself more efficiently. .NET is really slow across broad areas, and this kind of unnecessary overhead is a major reason why, because *nothing* comes without performance or resource footprint cost. Don't follow their example. Build clean, simple designs that *get* *the* jobs done. We used to say, "Keep it simple, STUPID." (KISS)
|
|
|
|
|
Ohhhhh, Kataric! When he said "KATARIC" I thought it was an acronym with which I'm unfamiliar.
Like, maybe, "Keep All The Access Rights In Check" or something.
|
|
|
|
|
Well, I just spent another five hours reworking my MouseTrap class.
It's way better than what I did yesterday. I'll probably write an article on it, but if you'd like be beta testers let me know.
|
|
|
|
|
I got it working guys. The MouseDown worked it seems.
This ended up being my solution.
//Init Function
this.button[i].MouseDown += new MouseEventHandler(Quest202_MouseDown);
//Handler Functions
private void Quest202_MouseDown(object sender, MouseEventArgs e)
{
switch(e.Button)
{
case MouseButtons.Left:
OnLButtonDown(sender);
break;
case MouseButtons.Right:
OnRButtonDown(sender);
break;
}
base.OnMouseDown(e);
}
private void OnLButtonDown(object sender)
{
Button temp = sender as Button;
if (temp != null)
temp.BackColor = Color.Red;
return;
}
private void OnRButtonDown(object sender)
{
Button temp = sender as Button;
if (temp != null)
temp.BackColor = Color.Black;
return;
}
Thank you for all your help. I really appreciate it.
|
|
|
|
|