I have a windows forms application in which I instantiate another form (from the main form) and call it's Show() method. For some reason I am unable to receive any mouse events on the child form (there are no controls on it). Mouse events work fine on the parent form (in the area with no controls).
However, I can get mouse events to work on the child form if I override the base class method.
protected override void OnMouseDown(MouseEventArgs e)
{
// This works fine
}
This seems totally wrong. What is happening that I'm missing?
I finally figured it out. I created a custom constructor for the child form. It didn't call the
InitializeComponent() method that you see in the normal constructor. Frankly I have no idea what the initializeComponent method does, but I do know that it wont let you have any mouse events. Although this is kinda stupid I hope that it might save somebody else a headache.
I should have chained my overloaded constructors like this:
public ChildForm(... params ...) : this()
{
// code here...
}
Related
I'm working on a semi-professional project and needed a custom view for one of my models. As far as I could figure out that meant creating a UserControl-inherited class, like so:
public partial class PopulationView : UserControl
{
...
}
Now this works wonders, and I've been able to do pretty much all I wanted, including custom painting with onPaint but I've noticed none of the events seem to be registering. I've had to attach multiple event listeners and in all instances I end up going back to my form and adding an event listener to my custom component's instance in the form. For example, I'd like to add a Click event listener. What I try first is simply
public partial class PopulationView : UserControl
{
private void PopulationView_Click(object sender, EventArgs e)
{
Debugger.Break();
}
}
of course attaching the function to the Click event through PopulationView.cs [Design]. That doesn't work so I end up adding a Click event listener on the instance of the component and adding the PopulationView_Click function to my form (MainForm.cs [Design]) instead and launching the appropriate function on the control.
I feel that I'm missing something very simple which is preventing me from being able to register events in my control directly and I'd appreciate any help with this. I dug around the interwebs but couldn't find anything relevant.
Update
Some of the comment make me think I should provide more detailed information about what I'm doing. The setup is sort of complicated but here's a summary:
I have a custom control inheriting from UserControl, called PopulationView
I have an instance of that control added to a form
Attaching event listeners through the design view of the form to the instance of the control (listener in form itself) works. Adding them through PopulationView's design view (listener in PopulationView) does not.
What complicates thing is I have a BackgroundWorker in my form which is in charge of generating the PopulationModel for the PopulationView. Once that BackgroundWorker is done, it uses a BeginInvoke to tell the PopulationView it's time to draw.
However, all events behave the way described even before the BackgroundWorker is triggered with RunWorkerAsync. Is it possible it's still interfering?
Editing the PopulationView constructor, I had accidentally deleted the call to InitializeComponent(), where all the Designer code was. Silly, really. If you're ever using the Designer, make sure you call InitializeComponent from your constructor.
I have this very strange bug... Whenever i make a new form inside my main class, main form is called as well... For example, if I do something like this:
private void Player_Load(object sender, EventArgs e)
{
Options options = new Options(categoryList, stationList, styleManager1, 0, this);
}
the main form is showed as well... I mean, the original one, plus the new one... Its not the Options class constructor, i checked it... Does anyone know why this is happening?
It sounds like Options is an MDI child form, and your main form is the MDI parent.
If not - put a breakpoint on your main form's Activate or Load events and look at the stack trace - this will tell you how & where it's being triggered.
Sorry first, because I see another question, but both of the ans. and ques. is not clear enough
How can I raise a parent event from a user control in WPF?
In my MainWindow.xaml, I had a right Panel
<local:RightSideContent x:Name="RightPanel" Grid.Column="1">
So in the MainWindow.xaml.cs, if I want rise an event to this panel, I made the code like this:
public delegate void Event1();
public MainWindow()
{
this.InitializeComponent();
Event1 obj = new Event1(this.RightPanel.func);
obj();
// Insert code required on object creation below this point.
}
And in RightPanel class, I declare the function func
The question is: if I am in the RightPanel Class, how I raise an event to the MainWindow, because I can't wrote something like this.RightPanel.func.....
And by the way I am in another class that do not have xaml file, if I want raise an event to a UserControl, how can I do?
Sorry, I don't quite have enough rep to post a comment to clarify, but as I see it, there are three possible things you are trying to do here.
You are trying to trigger an event on MainWindow, from some code that doesn't reside in MainWindow. In which case, you need to make sure that you have a reference to MainWindow, and that there is a public method on MainWindow that will trigger that event.
You want MainWindow to handle a click etc that comes from RightPanel. In that case you simply put a Button.Click="blah" (or whatever the event is) attribute on your MainWindow, and it will catch any button clicks from below it that are not handled lower down. In fact you can even handle it lower down and make sure that you set the EventArgs so that it is effectively unhandled, so that you can then handle it higher up as well.
You want to be able to handle a custom event generated in RightPanel, in a similar way to the way you would the button click scenario from item 2 above. In this case, I would direct you to http://msdn.microsoft.com/en-us/library/ms742806.aspx which is the documentation for Routed Events in WPF, and you should be able to work out how to create your own RoutedEvent from there.
I am currently developing a Windows app with several forms. I use Form_Shown in one of those forms to execute some code to initialize (refresh) the form before showing it.
In Form.Shown Event on MSDN, it states that the event is raised only the first time the form is shown. However, I want to be able to execute code to initialize my form every time that I call Form.Show() in some of the forms. Here's an example.
From a form named Game. Contains an event handler Game_Shown and a button that when clicked shows a form named Menu:
private void btnMenu_Click(object sender, EventArgs e)
{
this.Hide();
Formulaires.formMenu.Show();
}
private void Game_Shown(object sender, EventArgs e)
{
Code here...
this.Refresh();
}
From the form named Menu. Contains a button that when clicked shows the form named Game:
private void lblGame_Click(object sender, EventArgs e)
{
this.Hide();
Formulaires.formGame.Show();
}
It is behaving by design.
From the docs:
The Shown event occurs whenever the form is first shown.
Also, you should not handle the Shown event in your class, rather you should override OnShown.
To achieve what you want, you might try overriding the OnVisibleChanged method. Inside the method, if the form is visible, then execute your code.
Like the Shown event, you should not handle it in your form class, instead override the appropriate method:
From the docs:
The OnVisibleChanged method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class.
What you want requires some detailed knowledge about which event happens when in the WinForm lifecycle. That may be documented somewhere, I don't know.
This is how I would find out:
create a small test project with 2 forms (Main and helper)
add the show and hide buttons and make sure it works.
Add Debug.Print("EventName") to all the candidate events of the helper form.
Look at the log in the output window and pick your event.
Candidate events would be FormClosing, FormClosed, (De)Activated, Enter, Leave, Load, ... go through the list.
When you find the right one, please post it here in an answer.
I need to change a certain DataGridView's property (a DataSourceUpdateMode for one of its binding) only when ALL of its initial data bindings are completed.
I tried subscribing to the "DataBindingComplete" event, but it's fired too many times (one or more time for each binding associated to the control); what I need is a more global "AllDataBindingsComplete" event, fired when the control is ready to be displayed to the user.
As a temporary workaround, I'm using the MouseDown event (I've assumed that when the user is able to click the control, it means that the control is displayed... :) and the events I'm playing with - SelectionChanged - are fired after the MouseDown):
protected override void OnMouseDown(MouseEventArgs e)
{
Binding selectedItemsBinding = this.DataBindings["SelectedItems"];
if (selectedItemsBinding != null)
{
selectedItemsBinding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
}
base.OnMouseDown(e);
}
It works, but it smells like an ugly hack A LOT (and it's called too many times, only one time is enough for my needs).
Is there a better way?
(yes, I'm trying to adopt MVVM in a Windows Forms project, and I've added a bindable "SelectedItems" property to the DataGridView...)
What I've done at the Windows Forms form level, and may be improvised down to just the control(s) you want, is to subclass the Windows Forms baseclass into my own. Then, in its constructor, attach an extra event call to the Load() event.
So when everything else is completely loaded, only THEN will it hit my custom method (of the subclass). Since it is the bottom of the call-stack chain being attached to the event queue, I know it's last and everything else is done... Here's a snippet of the concept.
public class MyForm : Form
{
public MyForm()
{
this.Load += AfterEverythingElseLoaded;
}
private void AfterEverythingElseLoaded(object sender, EventArgs e)
{
// Do my own things here...
}
}
This concept can be applied to the Init() function too if that's more appropriate for your control... Let everything else within it get initialized(), then do you the "AfterInitialized()" function.