Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / January 2008

Tip: Looking for answers? Try searching our database.

Passing events from the menu to a control

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
michael sorens - 09 Jan 2008 23:49 GMT
I created a user control that handles certain keystrokes, e.g. Ctrl-C for
cut, Ctrl-V for paste, plus other more specialized keystrokes. I want to list
these in the menubar like any other menu items. Once I assign a Shortcut Key
to the menu item, that menu sees the event before the control, as one would
expect. The question is, then, inside the menu item handler what code do I
need to pass on the keystroke to a control? This is slightly complicated by
the fact that the keystroke could go to any one of several controls,
depending on which is active. I have not been successfully in web searches on
this topic so far.
Environment: .Net 3.0, VS2005, C#.
Linda Liu[MSFT] - 10 Jan 2008 06:38 GMT
Hi Michael,

Based on my understanding, you have a UserControl that handles certain
short keys and you'd like to set these keys as the shortcut keys of some
menu items. The problem is that you don't know what code you should write
in the menu item Click event handler because the key stroke could go to any
one of several controls, depending on which is ative. If I'm off base,
please feel free to let me know.

Firstly, I don't think it makes any difference after you assign the
shortcut keys of the menu items. You can still use the ActiveControl
propetry of the form to determine which control in the form is active
currently.

I will illustrate this with an example. It requires you to add a MenuStrip
with a menu item to a form. The menu item has a shortcut key of Ctrl+W. It
also requires you to add two TextBoxes onto the form. In the menu item's
Click event handler, write down the following code:

private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
           TextBox txtbox = this.ActiveControl as TextBox;
           if (txtbox != null)
           {
               txtbox.Copy();
           }
}

Build the project and run the application. Type some text into one of the
two TextBoxes and select some text in it. Whether you click the menu item
on the form or press Ctrl+W, the selected text is copied to the Clipboard.

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
michael sorens - 10 Jan 2008 17:54 GMT
Thanks for the suggestions, but that is not quite what I need. Your code
sample uses the approach of explicitly calling methods to do specific
actions. What I need to do is different--I just want the menu item handler to
"get out of the way". By that, I mean I want it to pass on the keystroke
event so that whatever would have happened to the keystroke (if the menu
handler did not intercept it) happens.
To put this another way, if the menu item event provided a KeyPressEventArgs
argument instead of an EventArgs argument, the menu item handler would simply
set the Handled property to false, allowing the KeyPress event to "pass
through".
Linda Liu[MSFT] - 14 Jan 2008 06:23 GMT
Hi Michael,

Thank you for your reply!

We can call the SendKeys.Send method to send keystrokes to the active
application. In your scenario, you can call the SendKeys.Send method to
send the shortcut key of the menu item to the application so as to "pass"
on the key stroke event.

For example, we use Ctrl+O as the shortcut key of a menu item. In the Click
event handler of this menu item, add the following line of code to send
Ctrl+O to the application.

private void toolStripMenuItem1_Click(object sender, EventArgs e)
 {
           SendKeys.Send("^o");
 }

For more information on the SendKeys.Send method, you may refer to the
following MSDN document:

http://msdn2.microsoft.com/en-us/library/system.windows.forms.sendkeys.send.
aspx

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support
michael sorens - 14 Jan 2008 23:31 GMT
What you suggest will simply cause an infinite loop--it will return to the
exact same handler, unless you have some trick to do otherwise that you do
not mention. (And besides that, I do not believe that invoking what is
essentially a debugging aid for routine code would really be considered a
"best practice" for this scenario.)
Peter Duniho - 15 Jan 2008 01:22 GMT
> What you suggest will simply cause an infinite loop--it will return to  
> the
[quoted text clipped - 3 lines]
> essentially a debugging aid for routine code would really be considered a
> "best practice" for this scenario.)

Here's the thing: there is no public method in Control that will allow you  
to just pass along the data from a key event.

You mentioned in a previous post that you'd like to be able to just set a  
"Handled" property to false, but this only works when you're in the same  
chain of event handlers for an event.  You're trying to translate an event  
that occurs in one object to be handled by event handling in a different  
object.  At least, that's how your posts read.

Given what you've written so far, I think Linda's replies are quite  
appropriate.  Her first suggestion is in fact what I would have suggested  
given your question, and her second suggestion seems like the most obvious  
alternative given your refusal to just use the simple solution of calling  
methods directly.

It's difficult for me, reading your question, to know _exactly_ what it is  
you're trying to do.  It's possible that you're not getting answers that  
you find useful because you haven't really described your question very  
well.

As an example of the vagueness of your question: we do not even know which  
menu class you're using.  I mean, I suppose we can assume you're dealing  
with a ToolStrip menu, with ToolStripMenuItem instances.  But you haven't  
said that explicitly.

As another example: you've provided no simple code sample to illustrate  
how your code works now, nor to illustrate what sort of architectural  
design you'd like to implement.  In the latter case, you wouldn't  
necessarily need to provide working code (obviously :) ).  Just code that  
_looks_ like what you think the final solution should look like.

It's _possible_ that your question could be answered by suggesting that  
you subclass ToolStripMenuItem and override a method like ProcessCmdKey()  
or ProcessDialogKey(), or by suggesting that you set up some sort of  
"keystroke received" event that the active control can subscribe to and  
which you raise in response to receiving a keystroke in your menu.

But with such a vague question, it's going to be very hard to say for sure.

Pete
michael sorens - 15 Jan 2008 03:40 GMT
I want to say first, Pete, that I appreciate you taking the time to put down
your thoughts so thoroughly. My comments:

(1) My rejection of the "simple" solution was not on a whim; I do not have
exposed methods to call needed by that solution (which I should have stated).

(2) I maintain that the SendKey suggestion is an infinite loop--yet you say
this is "appropriate"; please explain how.

(3) Regarding your comment "You're trying to translate an event  
that occurs in one object to be handled by event handling in a different
object." That was present, in fact, for precisely the reason of
disambiguating what I wanted. I was giving a related example--note that I
said "IF it provided ...". (Sounds like I am damned if I do, damned if I
don't :-)

(4) Yes, I am referring to ToolStripMenuItems. I was not aware there were
other types, a fact reinforced by Linda's use of it in both examples.

(5) As for example code I cannot offer much beyond what Linda has already
provided twice:
private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
   // This menu command needs to pass the event--or perhaps
   // generate a different event--so that the approrpriate
   // event handler in a custom user control will act on the user's cmd.
}
For another example, consider the ordinary TextBox. It supports a variety of
keystrokes: cut, copy, paste, home, end, select-all, etc. I just want to add
those types of keys to a menu in the menu bar so that they are enumerated
along with all the menu commands that I am providing explicit implementation
for. It sounds like the only simple way to do this is from Linda's first
suggestion, i.e. call the specific methods.

Anyway, thanks for keeping me on my toes.
Peter Duniho - 15 Jan 2008 05:13 GMT
> I want to say first, Pete, that I appreciate you taking the time to put  
> down
[quoted text clipped - 4 lines]
> exposed methods to call needed by that solution (which I should have  
> stated).

Whim or not, you did reject it.  It may be for good reason, but that  
doesn't change the desirability of using that solution.  Just the  
feasibility.

> (2) I maintain that the SendKey suggestion is an infinite loop--yet you  
> say
> this is "appropriate"; please explain how.

I don't see an infinite loop.  Presumably the Click handler that Linda  
posted resides in the Control that should receive the keyboard input, not  
the ToolStripMenuItem.  So, unless the Control upon receiving the keyboard  
input then turns around and somehow raises a Click event in the  
ToolStripMenuItem, where's the infinite loop?

Does your Control do that?

> (3) Regarding your comment "You're trying to translate an event
> that occurs in one object to be handled by event handling in a different
> object." That was present, in fact, for precisely the reason of
> disambiguating what I wanted. I was giving a related example--note that I
> said "IF it provided ...". (Sounds like I am damned if I do, damned if I
> don't :-)

Well, that's fine.  It's not how I read that post though.  It's not just a  
matter of having the event use a different EventArgs class.  There's just  
not even that event mechanism.  It wasn't clear from your post that was  
understood.

> (4) Yes, I am referring to ToolStripMenuItems. I was not aware there were
> other types, a fact reinforced by Linda's use of it in both examples.

ToolsStripMenuItem is the most common, but there are legacy classes that  
you could have been using instead.  In any case, you should always be  
specific, even if in theory there are no other alternatives.

> (5) As for example code I cannot offer much beyond what Linda has already
> provided twice:
[quoted text clipped - 4 lines]
>     // event handler in a custom user control will act on the user's cmd.
> }

Well, first...those are Linda's examples, both of which you said were  
inappropriate.  How are we supposed to know that those actually do serve  
as examples of what you're trying to do?

Secondly, those are hardly complete enough to really understand the  
issue.  They don't tell us anything about the Control classes you're  
trying to interface with, or about how you'd prefer them to work.

Based on the code you posted above, either of Linda's suggestions would  
work fine.  Since you say they don't work fine, obviously the above  
example is not nearly specific enough to provide useful advice to you.  
You need to provide an example that is at least complete enough for people  
to understand why the simple example's Linda's offered don't work.

> For another example, consider the ordinary TextBox. It supports a  
> variety of
[quoted text clipped - 5 lines]
> for. It sounds like the only simple way to do this is from Linda's first
> suggestion, i.e. call the specific methods.

Well, the TextBox class has all of those specific methods (well, cut,  
copy, paste, home, end, and select-all...I don't know what's left in  
"etc." so I can't comment on that).  But you wrote "I do not have exposed  
methods to call needed by that solution".

So what's really the problem?

> Anyway, thanks for keeping me on my toes.

You're welcome.  :)

Pete
michael sorens - 15 Jan 2008 21:46 GMT
Regarding the infinite loop debate, you state "Presumably the Click handler
that Linda posted resides in the Control that should receive the keyboard
input, not  
the ToolStripMenuItem." But no, Linda's handler is in the menu item.
Furthermore:
(a) If the handler is in the control, how is it supposed to get the event,
since the menu got it first?
(b) But say the control does get the event--then why would I need the click
handler? That is the whole point, to get the event to the control.

One of us, I think, is missing some assumption here since this issue is in
dispute; but I am not sure if it is you or me :-)

In any case, it is not terribly crucial, as I think I have gained what I am
able from this thread.

Thanks for all the input.
Peter Duniho - 15 Jan 2008 22:13 GMT
> Regarding the infinite loop debate, you state "Presumably the Click  
> handler
> that Linda posted resides in the Control that should receive the  
> keyboard input, not
> the ToolStripMenuItem." But no, Linda's handler is in the menu item.

Why do you say that?  Nothing in Linda's post says that the handler "is in  
the menu item", and it flies in the face of logic that it would be.

If for no other reason than that if it were, there's the possibility of an  
infinite loop whereas if it's in the control, such a problem is avoided.  
Also note that you specifically said you wanted to send the key to the  
control...since her code does not qualify a specific control in the call  
to the SendKeys() method, it stands to reason that the method is contained  
within the control class that should receive the key input.

Why do you insist on believing that she posted useless code, rather than  
accepting the possibility that maybe you misunderstand the code?

> Furthermore:
> (a) If the handler is in the control, how is it supposed to get the  
> event,
> since the menu got it first?

Huh?  A handler for any event can be anywhere in any class.  It "gets the  
event" by subscribing to the event.  When the event is raised, it gets the  
event.

Whether the menu "got it first" or not is irrelevant.  There's not even  
any reason to believe that the menu has a handler subscribed to the  
event.  The ToolStripMenuItem class itself is unlikely to have subscribed  
to the event, so unless you've sub-classed the class and written your own  
event handler which you've subscribed to the event, the menu would not in  
fact have a handler subscribed to the event.

> (b) But say the control does get the event--then why would I need the  
> click
> handler? That is the whole point, to get the event to the control.

Well, it is in fact hard to understand what your problem is.  I don't in  
fact understand why you wouldn't just subscribe an event handler in the  
control to the menu's event.  But since you prefer to complain about the  
answers given rather than elaborate on what the actual problem is, you  
continue to apparently not receive the help you desire.

> One of us, I think, is missing some assumption here since this issue is  
> in
> dispute; but I am not sure if it is you or me :-)

I am sure it is you.

> In any case, it is not terribly crucial, as I think I have gained what I  
> am
> able from this thread.

Does that mean that your problem is solved?  If so, how is it solved?

Pete

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.