Break code execution from base class in inherited form
-
I fear this question has been asked a thousand times, but the keywords I can think of are too common and give millions of answers and I can't find the correct one. In a Windows forms application (C# 2008) I have a base form with a datagridview on it, and I want to catch the cell click events on the descendants. If the contents of the datagridview is clicked I have to create a custom event, but if columnhead is clicked I allways want the same event. I hoped I could achieve this by defining the common event in the base class, followed by the custom event in the descendant. I defined a break in the code of the base class when column head is clicked, the break is correctly handled, but the code resumes in the descendant's form class. How can I stop the code execution in the descendant form if I have a break in the base class ? Thanks Rob
-
I fear this question has been asked a thousand times, but the keywords I can think of are too common and give millions of answers and I can't find the correct one. In a Windows forms application (C# 2008) I have a base form with a datagridview on it, and I want to catch the cell click events on the descendants. If the contents of the datagridview is clicked I have to create a custom event, but if columnhead is clicked I allways want the same event. I hoped I could achieve this by defining the common event in the base class, followed by the custom event in the descendant. I defined a break in the code of the base class when column head is clicked, the break is correctly handled, but the code resumes in the descendant's form class. How can I stop the code execution in the descendant form if I have a break in the base class ? Thanks Rob
That's how subtyping works. When you crete an instance of the child class, all code is executing against that instance. If the base class defines handlers for events like in your case, it still executes against that instance of the child class you created. But what is it that's not working? Both events can be defined on the base class, like so:
internal abstract class MyFormBase : Form
{
DataGridView dataGridView1;protected MyFormBase()
{
dataGridView1 = new DataGridView();
dataGridView1.CellClick += OnDataGridViewCellClick;
// Other initialization
}protected virtual string Message
{
get { return "Message from the base class."; }
}protected virtual void OnDataGridViewCellClick(object sender, DataGridViewCellEventArgs e)
{
// Override this in your child class if you wish.
}protected virtual void OnDataGridViewColumnHeaderMouseClick(object sender, DataGridViewBindingCompleteEventArgs e)
{
MessageBox.Show(Message, "Test");
}
}internal class MyChildForm : MyFormBase
{
protected override string Message
{
get { return "Message from the child class."; }
}protected override void OnDataGridViewCellClick(object sender, DataGridViewCellEventArgs e)
{
MessageBox.Show("You clicked a cell.", "Test");// Example of how to call a base method. Not always required, and in this case doesn't do anyway. // However, for some virtual methods it's very important to call the base so read documentation. base.OnDataGridViewCellClick(sender, e);
}
}Now when you create an instance of MyChildForm and click a column header, you'll see "Message from the child class" even though the event handler is defined in the base class. It calls the virtual (overridable) property which IS the property on the MyChildForm instance. If you want to call the base class's method, use
base
. You also overrided the CellClick event handler which will show "You clicked a cell." I also show an example of calling the base class's method though in this case it doesn't do anyway. If it would never do anything, define it asabstract
instead ofvirtual
and remove the body like so:private abstract void OnDataGridViewCellClick(object sender, DataGridViewCellEventArgs e);
Hopefully this shows you an example of how polymorphism is working such that you can define your handlers in your base class but have it access the data - expectedly - in the child class.
-
That's how subtyping works. When you crete an instance of the child class, all code is executing against that instance. If the base class defines handlers for events like in your case, it still executes against that instance of the child class you created. But what is it that's not working? Both events can be defined on the base class, like so:
internal abstract class MyFormBase : Form
{
DataGridView dataGridView1;protected MyFormBase()
{
dataGridView1 = new DataGridView();
dataGridView1.CellClick += OnDataGridViewCellClick;
// Other initialization
}protected virtual string Message
{
get { return "Message from the base class."; }
}protected virtual void OnDataGridViewCellClick(object sender, DataGridViewCellEventArgs e)
{
// Override this in your child class if you wish.
}protected virtual void OnDataGridViewColumnHeaderMouseClick(object sender, DataGridViewBindingCompleteEventArgs e)
{
MessageBox.Show(Message, "Test");
}
}internal class MyChildForm : MyFormBase
{
protected override string Message
{
get { return "Message from the child class."; }
}protected override void OnDataGridViewCellClick(object sender, DataGridViewCellEventArgs e)
{
MessageBox.Show("You clicked a cell.", "Test");// Example of how to call a base method. Not always required, and in this case doesn't do anyway. // However, for some virtual methods it's very important to call the base so read documentation. base.OnDataGridViewCellClick(sender, e);
}
}Now when you create an instance of MyChildForm and click a column header, you'll see "Message from the child class" even though the event handler is defined in the base class. It calls the virtual (overridable) property which IS the property on the MyChildForm instance. If you want to call the base class's method, use
base
. You also overrided the CellClick event handler which will show "You clicked a cell." I also show an example of calling the base class's method though in this case it doesn't do anyway. If it would never do anything, define it asabstract
instead ofvirtual
and remove the body like so:private abstract void OnDataGridViewCellClick(object sender, DataGridViewCellEventArgs e);
Hopefully this shows you an example of how polymorphism is working such that you can define your handlers in your base class but have it access the data - expectedly - in the child class.
Thanks for your answer, although it is not what I wanted to hear.... Perhaps I was unclear, I'm creating an application with over a dozen forms with a datagridview on it. The datagridview contains buttons, and their action is dependent on the child form. In the cellclickevent I get the rownumber, and when it's -1 the columnheader is clicked. I want all child forms to ignore the click of the columnheader and I wanted to achieve it like: child form: protected override void dgvSelect_CellClick(object sender, DataGridViewCellEventArgs e) { base.dgvSelect(sender, e); custom cell click events; } I will solve it like this: protected override void dgvSelect_CellClick(object sender, DataGridViewCellEventArgs e) { if (base.dgvSelectHeaderClicked(sender, e) == true) { return; } custom cell click events; } Thanks for your time. Rob
-
That's how subtyping works. When you crete an instance of the child class, all code is executing against that instance. If the base class defines handlers for events like in your case, it still executes against that instance of the child class you created. But what is it that's not working? Both events can be defined on the base class, like so:
internal abstract class MyFormBase : Form
{
DataGridView dataGridView1;protected MyFormBase()
{
dataGridView1 = new DataGridView();
dataGridView1.CellClick += OnDataGridViewCellClick;
// Other initialization
}protected virtual string Message
{
get { return "Message from the base class."; }
}protected virtual void OnDataGridViewCellClick(object sender, DataGridViewCellEventArgs e)
{
// Override this in your child class if you wish.
}protected virtual void OnDataGridViewColumnHeaderMouseClick(object sender, DataGridViewBindingCompleteEventArgs e)
{
MessageBox.Show(Message, "Test");
}
}internal class MyChildForm : MyFormBase
{
protected override string Message
{
get { return "Message from the child class."; }
}protected override void OnDataGridViewCellClick(object sender, DataGridViewCellEventArgs e)
{
MessageBox.Show("You clicked a cell.", "Test");// Example of how to call a base method. Not always required, and in this case doesn't do anyway. // However, for some virtual methods it's very important to call the base so read documentation. base.OnDataGridViewCellClick(sender, e);
}
}Now when you create an instance of MyChildForm and click a column header, you'll see "Message from the child class" even though the event handler is defined in the base class. It calls the virtual (overridable) property which IS the property on the MyChildForm instance. If you want to call the base class's method, use
base
. You also overrided the CellClick event handler which will show "You clicked a cell." I also show an example of calling the base class's method though in this case it doesn't do anyway. If it would never do anything, define it asabstract
instead ofvirtual
and remove the body like so:private abstract void OnDataGridViewCellClick(object sender, DataGridViewCellEventArgs e);
Hopefully this shows you an example of how polymorphism is working such that you can define your handlers in your base class but have it access the data - expectedly - in the child class.
Holy shit! A rare sighting of the elusive Heath Stewert!! I am honored to be in the presence of the greatness of one of CP's legends. ;)
A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
Holy shit! A rare sighting of the elusive Heath Stewert!! I am honored to be in the presence of the greatness of one of CP's legends. ;)
A guide to posting questions on CodeProject[^]
Dave KreskowiakThanks! :-D I might have to make that first one part of my sig.
This posting is provided "AS IS" with no warranties, and confers no rights. Program Manager II Visual Studio Professional Deployment Experience Microsoft [My Articles] [My Blog]