T
TheSilverHammer
I have two examples where I need to do this:
Example 1:
Lets say that I have a bunch of TextBox's on a form. All these textbox
objects share a common KeyPress event which validates the input to make sure
that it is a number, control character (IE: Backspace, enter key) or special
symbol such as '.' or '-' so you can have numbers like 1.2 or -12.
Each of these textboxes also have an event for "Leave" which is unique to
each textbox, and these leave events update a data structure which is
relevant to the particular textbox.
What I would like to do is is have the generic "KeyPress" event handler look
for the enter key and then fire off the leave event for the particular
textbox. The code will look something like this:
// Handle an Enter key
if ( 13 == e.KeyChar )
{
TextBox TB = sender as TextBox;
// Call Event Here
}
The "Call Event Here" might be TB.OnLeave(), but these methods are protected
so I can't call them. There doesn't appear to be any kind of SendMessage
API or any way to tell TextBox TB to run its Leave event. In the MFC days,
you would just send a message like SendMessage(WM_LEAVE) or something like
that.
The only solution I can see here is do to something clunky like:
if ( ReferenceEquals(TB, textBoxAlpha) ) { // Call textBoxAlpha leave event
if ( ReferenceEquals(TB, textBoxBeta)) { // Call textBoxBeta leave event
etc...
It seems that there must be a better way. If you have abstract control X
and you know it has a handler for Event Leave(), why can't you invoke the
event?
The windows form does it, but it is all hidden and there is no source code
to step through to see how it is all done.
Example 2:
I have a user control, which has a FlowLayout Panel which has other user
controls in them. The user controls in the panel are mostly just visual
meaning that you do not interact with them directly, however I want to know
if anyone clicks on one of the controls. I want the higher level user
control that owns the panel, that owns the collection of 'visual' user
controls, to know if anyone clicks on one of these visual user controls.
To make matters more complicated is the fact that the visual controls have
other controls on them like static text boxes. If a user clicks on one of
those, even the 'visual' control doesn't see the event. This is kind of a
Parent Notify thing that seems to be missing.
The way I manged to do this was to override the WinProc for the base class
of my Visual controls to sniff for the click message and then issue its own
click event to itself (which is just about the only thing you can do). The
User control that has the panel of these visual controls just adds a
ClickEvent to the visual user control which lets it know whenever someone
clicked on it.
It works, but seems like a round about way of doing this and it requires you
to get into the guts of the WinProc and know what messages to look for. I
could not have done this unless I found some that gave this kind of example.
Here is the function that does the trick:
protected override void WndProc(ref Message m)
{
//0x210 is WM_PARENTNOTIFY
if (m.MSG == 0x210 && m.WParam.ToInt32() == 513) //513 is
WM_LBUTTONCLICK
{
this.OnClick(new EventArgs());
}
base.WndProc(ref m);
}
There are some nice magic numbers there which I would not have found in any
C# documentation.
So, is there a way to do this without all this low-level stuff?
I do not understand why the OnEvent() methods are protected instead of
public or why there isn't a SendMessage() function of some kind. It seems
that the GUI api classes are locked up tight and only Microsoft is allowed to
send anyone message or events.
Example 1:
Lets say that I have a bunch of TextBox's on a form. All these textbox
objects share a common KeyPress event which validates the input to make sure
that it is a number, control character (IE: Backspace, enter key) or special
symbol such as '.' or '-' so you can have numbers like 1.2 or -12.
Each of these textboxes also have an event for "Leave" which is unique to
each textbox, and these leave events update a data structure which is
relevant to the particular textbox.
What I would like to do is is have the generic "KeyPress" event handler look
for the enter key and then fire off the leave event for the particular
textbox. The code will look something like this:
// Handle an Enter key
if ( 13 == e.KeyChar )
{
TextBox TB = sender as TextBox;
// Call Event Here
}
The "Call Event Here" might be TB.OnLeave(), but these methods are protected
so I can't call them. There doesn't appear to be any kind of SendMessage
API or any way to tell TextBox TB to run its Leave event. In the MFC days,
you would just send a message like SendMessage(WM_LEAVE) or something like
that.
The only solution I can see here is do to something clunky like:
if ( ReferenceEquals(TB, textBoxAlpha) ) { // Call textBoxAlpha leave event
if ( ReferenceEquals(TB, textBoxBeta)) { // Call textBoxBeta leave event
etc...
It seems that there must be a better way. If you have abstract control X
and you know it has a handler for Event Leave(), why can't you invoke the
event?
The windows form does it, but it is all hidden and there is no source code
to step through to see how it is all done.
Example 2:
I have a user control, which has a FlowLayout Panel which has other user
controls in them. The user controls in the panel are mostly just visual
meaning that you do not interact with them directly, however I want to know
if anyone clicks on one of the controls. I want the higher level user
control that owns the panel, that owns the collection of 'visual' user
controls, to know if anyone clicks on one of these visual user controls.
To make matters more complicated is the fact that the visual controls have
other controls on them like static text boxes. If a user clicks on one of
those, even the 'visual' control doesn't see the event. This is kind of a
Parent Notify thing that seems to be missing.
The way I manged to do this was to override the WinProc for the base class
of my Visual controls to sniff for the click message and then issue its own
click event to itself (which is just about the only thing you can do). The
User control that has the panel of these visual controls just adds a
ClickEvent to the visual user control which lets it know whenever someone
clicked on it.
It works, but seems like a round about way of doing this and it requires you
to get into the guts of the WinProc and know what messages to look for. I
could not have done this unless I found some that gave this kind of example.
Here is the function that does the trick:
protected override void WndProc(ref Message m)
{
//0x210 is WM_PARENTNOTIFY
if (m.MSG == 0x210 && m.WParam.ToInt32() == 513) //513 is
WM_LBUTTONCLICK
{
this.OnClick(new EventArgs());
}
base.WndProc(ref m);
}
There are some nice magic numbers there which I would not have found in any
C# documentation.
So, is there a way to do this without all this low-level stuff?
I do not understand why the OnEvent() methods are protected instead of
public or why there isn't a SendMessage() function of some kind. It seems
that the GUI api classes are locked up tight and only Microsoft is allowed to
send anyone message or events.