views:

636

answers:

4

In my application I am running the same winform in different contexts to control visibility of buttons, enabeling of text fields and the winform header text. The way I decided to do this is simply by passing a string to the form constructor and check it with a couple of if statements that in turn contain the desired winform tweaks.

if (formContext == "add")
{
    Text = "Add member";
}
if (formContext == "edit")
{
    Text = "Change role";
    userTextBox.Enabled = false;
    searchButton.Visible = false;
}

This works fine, however the "Text" keywords get a blue squigly line added by ReSharper with the following message: Viritual member call in constructor. Is this a potential problem or just some sort of overly enthusiastic ReSharper message.

Any clarification or suggestions for improvement of my implementation would be much appreciated.

+6  A: 

A virtual member call in the base class ctor could cause some logic to run in the subclass before the subclass' ctor is called (and thus before the object gets a chance to initialize itself to a consisten state).

It's just a nice reminder so you know you are doing something that could potentially cause some nasty unexpected behavior.

mookid8000
Yes... this is along the line I was thinking myself. Any suggestions as to how I could do this better. Stability is out number one priority on this project and I would prefer to avoid possible unexpected behavior.
Sakkle
You mean suggestions besides just not calling virtual methods in your base class ctor? :-)In this situation you could use data binding to bind the Text property of the form to a string field in a GUI model class which then would contain the necessary logic to decide what the title bar should say.
mookid8000
Yes... I probably could, though I wouldn't know where to start, and I guess I'd have to do the same for the button and the text field.
Sakkle
+5  A: 

In addition to the existing answers, for forms you could add a Load event handler:

Load += delegate
{
    if (formContext == "add")
    {
        Text = "Add member";
    }
    if (formContext == "edit")
    {
        Text = "Change role";
        userTextBox.Enabled = false;
        searchkButton.Visible = false;
    }
};
Jon Skeet
This seems like the easiest and best solution for what I am trying to accomplish, without me having to rewrite a lot of code. Yes... I am lazy :P
Sakkle
A: 

I would suggest rewriting you class as follows:

public partial class Form1 : Form
{
    public enum FormContextMode
    {
        Add,
        Edit
    }

    private FormContextMode m_mode = FormContextMode.Add; 

    public Form1( FormContextMode mode )
    {
        InitializeComponent();
        m_mode = mode;
        Load += delegate { UpdateForm(); };
    }

    private void UpdateForm()
    {
        if( m_mode == FormContextMode.Add )
        {
            Text = "Add member";    
        }
        else if( m_mode == FormContextMode.Edit )
        {
            Text = "Change role";
            userTextBox.Enabled = false;
            searchkButton.Visible = false;
        }
    }
}
ng5000
Ahaaa... sweet :)
Sakkle
You don't need to subscribe to own Load event, just override OnLoad method.
Ilya Ryzhenkov
Yep, I agree with Ilya - better to overload the method then you won't need to remember to unsubscribe from the event + (and this is a gut-feel statement) probably quicker.
ng5000
Don't create a "2nd answer", it's just confusing. This answer on its own does not meet the "Any clarification or suggestions for improvement" demand in the question.
bzlm
Original answer deleted and replaced with this one, updated as shown.
ng5000
+3  A: 

Just seal your class.

Ilya Ryzhenkov
Please elaborate...
Sakkle
http://msdn.microsoft.com/en-us/library/88c54tsw(VS.71).aspxA sealed class can not be inherited, therefor there is no possibility of a derived class overriding the virtual member.
ng5000