I am working with an existing WinForm application and it uses the following code to re-activate a child form that has previously been loaded:
private void Activate(Form frm)
{
frm.WindowState = FormWindowState.Maximized;
this.ActivateMdiChild(frm);
}
The trouble I'm having is that when the form is re-activated, I can not seem to find any event on the form that gets raised naturally by the code above. I'm also having difficulty adding code to manually raise the event on the child form, and I think it's because I'm working with a generic Form object.
I've tried Load, MdiChildActivate, MaximumSizeChanged, Activated and a few other events, and none of them fire upon running the code above. I basically need to update some of the form elements after that code is called above and figured an event would work well.
Does anyone know an event that will be raised on the child form after it has been reactivated?
Have you tried the Enter event of the child form? I don't think it fires if the form is already active though.
Another option would be to cast it as your own type and add your own event, then fire it directly.
Related
I have an application that contains a form with multiple controls.
I have subscribed to the form mouse up event. However when I click on the form if thewre is an other control placed on the form the event is not fired.
So, I would like to capture an form event on the form (even when an control is in place). Is this possible?
Thanks in advance.
As far as i know windows forms doesn't implement the concept of event bubbling. So you should manually tweak controls to handle the event. You can do it manually looping through all controls, or you can create some kind of wrapper for your form/container to subscribe to the event automatically. You may check general implementation of this idea here. .
I have tried a bunch of different things, so obviously I am now stuck... I have created a form, it has a button on it - that when clicked creates a new form. I can click away and create multiple forms this way. What I would like and can not get to work is to have the main form have a second button on it - that when clicked will change all of the background colors on the secondary forms.
Thanks - I am guessing I close, but then again - close doesn't work...
Bascally you do not need event or delegate type of things to solve this issue. In your secondary forms write a public method to change background color. Keep a list of secondary forms and when button is clicked just loop through all your secondary forms and call the color changing methods
Using events
In your parent form do something like this.
private event Action<Color> ChangeColor;
private void CreateAndShowForm()
{
var form2 = new Form2();
ChangeColor += form2.changeColor;
/*do other stuff to show form*/
}
private void button1_Click(object sender, EventArgs e)
{
ChangeColor(Color.Red);
}
In the child forms
public void changeColor(Color obj)
{
/*change background color*/
}
There are a few ways to achieve this, but one way is to keep a collection of all child Forms in the main form and call a custom change background color method on each of them. You can create a ChildFormBase class that they all can inherit from where you can define the method to avoid repeating it in all child forms.
You can also do this with an event that you raise in the MainForm that the child forms can subscribe to.
In .NET, when an event is raised, all the objects listening to it (registered as event listeners) are notified that the event has been raised and execute the respective event handler. Therefore, in your case, each subform should be registered to the specific event of the main form, as an event listener. Each time the main form raises the event, the subforms will be notified that the event has been raised and act accordingly.
You could see this as a guide to the events paradigm in C#.
Hope I helped!
I am working on a Browser Helper Object in C# (yes I know performance will not be great).
I am attaching a handler to the HTMLWindowEvents2_Event.onload event of my window. The event is being raised correctly (for example when a refresh happens). I see my handler being called, and the type is correctly shows as a 'load' event.
The event handler has a parameter that supports the IHTMLEventObj. I cannot work out how to get from this object to the window or document that threw the onload event. Is this even possible from this interface? The object passed into appears to have a null srcElement property (presumably as it is an event raised by the window, not some element in the document).
Do I need to cast this into another class or interface to get at the document?
I would be happy for any help in C# or C++.
There is no source information for the event.
The assumption is that since you attached the event to the connection point of the Window object, you knew which window would be the event source. When you hook the event you need to save the reference to the window in case you need the event source.
Class HTMLWindowEvents2Sink
{
public HTMLWindowEvents2Sink(IHTMLWindow2 eventSource)
{
this.eventSource=eventSource;
}
IHTMLWindow2 eventSource;
void AdviseEvent()
{
eventSource.load += this.HTMLWindow_onload;
}
....
}
You also have a performance hit and potential bug farm here, by using the delegate event handling model.
Simple question. I have a MainForm and a settingsForm. The settings form is initialized once and then shown every time the user clicks a button. I need it to do something when this button is clicked.
m_inputSettings.ShowDialog(this); //edit settings selected, so show that form
This is the MainForm calling the settings form, which it does fine. But I need the SettingsForm to do something every time this happens. Presently, I cant figure out if this call actually triggers any events I can set handlers for. Does it trigger an event? If not, is there another way I can tell my SettingsForm to do something every time this call happens?
Note: Any code in the mainform after that line doesn't get executed until the SettingsForm returns, but that is intentional.
Thanks.
Edit: One of the things I want my form to do it select a specific control when this happens, but it seems that that is impossible until after the form is done loading everything.
You can override the OnVisibleChanged method in your settings form. Make sure to call base.OnVisibleChanged though as to not screw up any potential observers of the event (and anything else the base class may do inside of that method.)
FormShown event - raised only once when form is displayed first time.
OnPaint / OnActivate - every time form is activated, but these events raised even when you switch with other application, which probably you don't want to do.
If you are changing form visbility, then you can use OnVisibleChanged
If you are minimizing the form, you can use OnSizeChanged / OnLocationChanged event.
If none suits you, make a public property and set false when form is closed / hidded, and set true before showing it. OnActivate, use this property to do your task.
Maybe use VisibleChanged event.
Override OnShown() event in your form this will raise only once after the form is opened
The disadvantage of OnVisibleChanged is it will also get raised when the form is closed.
On Paint , On Activate and OnEnter will raise before form is shown to the user.
I have two forms; one called 'win' and the other called 'loss'. There is a button on 'win' form which displays the 'loss' form. When this button is clicked both forms are visible. When I close the 'loss' form and then click the button on the 'win' form again I get the following exception:
An unhandled exception has occured: Unable to access a disposed object ..object :form
Please could someone point me in the right direction so I can resolve this?
It is because your 'loss' form is already closed and has been disposed, so it cannot be used anymore. You need to create a new instance of the form, like so (don't know how exactly your code looks):
this.loss = new LossForm();
this.loss.Show();
You can verify IsDisposed property of form, before referencing it.
E.g. button click handler on 'win' form:
if (loss.IsDisposed)
return;
// do stuff with loss form
Update: I think it's better not to share control between forms.
You can run 'loss' form as Dialog. And read all needed properties after dialog closed.
You can subscribe to 'loss' form events and process them in 'win' form.
It's not a very good model your going for but you could hook into the formClosing event, cancel it and then hide the form instead. That means the form wont be automatically disposed and you could call show again.
Put some time aside to research MVC architecture - it looks complicated at first, but it really does help.