Raising event from custom control added dynamically to the form - c#

I have a custom control that can be added multiple times to a form. There can be multiples occurrences of this custom control on the same form. These controls are added and removed by the user. The user can right click on some control inside the custom control to reveal a menu.
When selecting an item from this menu, an event should be raised on the form. I made a custom event and realized that it could't be usable if the control was added dynamically, because the form doesn't know it. I can't add an event handler referring to a control that doesn't exist. Is there some other way to raise an event on the form from custom control that doesn't require the form to know it? By the way, my custom controls are added to a FlowLayoutPanel.
Thanks for the help!

You just wire up the event handler in the code when you add the control e.g.
MyButton.Click += ButonClickEventHandler;
Page.Controls.Add(MyButton)

Agree with Ben - otherwise, there are messy ways of doing it (depending on how your control is set up). For example INotifyPropertChanged Inerface or through Windows API messaging (and listener) - but unless you have a very strange set up, then as Ben said, simply add a handler when you add the control. You can always use a generic callback method and use custom event args to identify which has triggered it.

Related

How to send mousedown message to a component or control?

Is there a way to send message (like mousedown) to a control?
My purpose is that when you click GridView, prevent mousedown behavior itself and bypass mousedown message to RepositoryItem.
From your question: "My purpose is that when you click GridView, prevent mousedown behavior itself and bypass mousedown message to RepositoryItem."
It sounds like you want to control the behavior of the Mouse Down event on the control. Right?
If that's the case, on the Winforms designer, look at the properties panel. On there is also a selection for the form events for a control. You can scroll down and find the Mouse Down event and add an event handler. Then do whatever filtering you need including not even processing the message at all.
You also mentioned that it's a DevExpress control. I recall that some of their controls were wired up a little differently so the DevExpress website might have some additional clues.

How to force validation of UserControl?

Validations for my textbox controls work normally/as expected. However, for my created UserControl, also containing a textbox (which also contains other controls as well), it's not always validated, except when the user manually selects/focuses another control, which will of course fire the Validating event.
Now, I've found from searches about Form.ValidateChildren() (which works btw), but this method validates all children as described in the documentation, which is not the ideal solution to a form with many controls, as opposed to only validating the single control in question.
Additional info:
I use ErrorProvider to show errors - I need to consider the position
of the icon in the case of my UserControl (which again, contains
multiple controls inside).
Validating and Validated events are performed on my UserControl, not the TextBox inside it. Both events are on the form where the usercontrol is used.
The Text property of the TextBox inside my UserControl is modified
internally (inside my UserControl class)
`
//some code inside usercontrol
private void SomeMethod()
{
...
textBox.Text = ...;
ParentForm.ValidateChildren(); // works but does this on all controls which is not the ideal operation, which is to perform validation only on this usercontrol
}
`
With the above-mentioned info, when I modify the Text property manually, the Validating event is, as expected on the design, not raised since UserControl.TextBox != UserControl. It's not an option for me to perform validation on the UserControl.TextBox instead of the UserControl.
With all that explained, how should I manually/forcefully trigger the validation only for the UserControl, when UserControl.TextBox.Text is modified, without resorting to Form.ValidateChildren which targets all of the form controls? Or is it not possible?

C#: Temporarily capture OnClick event in parent control

I have a Windows Forms application and I want to be able to show a 'post-it note' type thing when the user does a specific action.
For example: The user does something which automatically hides a control.
My application should:
o Pop up a post it note which explains what happened.
o Hide the post it note again when the user clicks anywhere on the form.
I have implemented the post it note as a simple panel with a label in it, which shows and hides when specific things happen.
However, I can't seem to capture the OnClick event of the parent UserControl. The parent control is a nested control, containing a split container, one side of which contains the panel and a tab control, each of which contains a user control with various things in it.
Apart from handling the click event of every single child control, can anyone think of an event that I can capture on the parent control that I can use to hide the post it note when the user clicks anywhere in the parent control?
Thanks,
Rik
That's what the Capture property was designed to do. Set it to true when you pop up the note. Any mouse events will now be directed to your control, even if the mouse moves outside of the window. This is also the way that, for example, the combobox dropdown list works. Keep in mind that it is only good for one click.
If the popup contains any controls itself then mouse capture isn't the solution. Make it an owned form instead and simply call Close() in an event handler for the Deactivate event.
There is bubling of events in windows form, while you click on child event, the event is raised for child, and then for parent. Unless you specify "handleEvnet" property to true. So just leave it false, untill event reaches parent.

How to expose/bubble events to outside in Composite Winforms Controls?

I have a CompositeControl with 3 buttons, and I don't want to have these buttons as public members from my CompositeControl. But I also want to expose their Click event individually so the user of this control can subscribe to them.
I am not sure how to do this without duplicating the same events in my control and raising each button's Click event separately.
I am not sure how to do this without duplicating the same events in my control and raising each button's Click event separately.
This is really the proper way to handle this. You will want to duplicate the event, but give it a new, proper name.
Typically, this means exposing the "click event" with a name that's related to the activity of the button, not the button itself. For example, if you had a refresh button, I'd expose the event as something like:
public event EventHandler RefreshRequested;
Then, internally, you'd listen to the button's click event and raise the refresh requested event. This also provides you the flexibility, later, to change the internal representation (if you wanted to use something other than a button, for example).

How do I add events to nested server controls? (ASP.Net)

I am building a custom master page type control i.e. sort of like a datagrid but should be easier to add custom functionality into it. It's going great but part of the desired functionality is to have a paging control that switches on and off and part of that control would be a textbox that displays the current page number and on TextChanged redirects to the new page of the dataset.
The problem I'm having is that technically the textbox which has its event fired is embedded in a control that is embedded in the control you actually put on the page sort of like
Page
|
Display Control
|
Paging Control
|
Textbox
Buried all the way down there the event is not firing. Worse the postback javascript isn't even being written onto the page (Nothing on the page posts back so far this is the only bit that really needs to).
I've been trawling around Google for quite a while now and picked up that I need to implement INamingContainer (done) and I need to add the control into the page's control tree (is Pre_Init too late for that? When's a good time to Add the Control to the page?) then the event should fire, apparently. But I've been unable to find an example of best practice on this there are quite a few near misses where people are having button angst but this isn't a button.
So can anyone point me in the direction of getting a control embedded in a control embedded in a control added to a page to behave properly?
You need INamingContainer only if you plan to add more than one instance of your custom control to the same page. What it does is enabling unique id generation so you don't end up with controls with the same ID. I recommend you inherit from CompositeControl when creating your custom control.
Pre_Init is not too late. Actually it is pretty early considering the lifecycle. You can instantiate custom controls and add them to the live controls collection in a lot of places. I would recommend you do it in Page_Init (before viewstate is loaded) or Page_Load(after view state is loaded). Even if you add it later in the page lifecycle the control will catch up in events.
To subscribe to events of child controls you can use the FindControl method:
MyControl myControl = Page.FindControl("MyControl1");
TextBox textBox = myControl.FindControl("TextBox1") as TextBox;
The answer was a combination of the above answer and the comment on the original question. The vital thing to get the event to happen is to make sure that your controls (parent and child) inherit from CompositeControl and INamingContainer e.g.
public partial myControl:CompositeControl,INamingContainer
etc...
Then you override your composite control's CreateChildControls() method and create your controls and do the wire up there. This will ensure correct bubbling. and mean that the event handling takes place within your comoposite control...

Categories