tags:

views:

1130

answers:

4

Hi,

I'm a newbie in C# bu I'm experienced Delphi developer. In Delphi I can use same code for MenuItem and ToolButton using TAction.OnExecute event and I can disable/enable MenuItem and ToolButton together using TAction.OnUpdate event. Is there a similar way to do this in C# without using external libraries? Or more - How C# developers share code between different controls?

A: 

You can enable or disable a control and all its children by setting its Enabled property.

VVS
A: 

Ok, may be I write my question in wrong way. I want to know not witch property to use (I know about Enabled property) but I want to know on witch event I should attach to if I want to enable/disable more than one control. In delphi TAction.OnUpdate event ocurs when Application is idle - is there similar event in C#?

The question is when do you want to enable/disable controls?
VVS
A: 

You can hook the code for the MenuItem and the ToolButton in the same handler. For example:
menuItem.Click += HandleClick;
toolbarButton.Click += handleClick;
This way clicking both the MenuItem and the Button will execute the same code and provide the same functionality.

sh_kamalh
+1  A: 

Try the a modification of the command pattern:

public abstract class ToolStripItemCommand
{
    private bool enabled = true;
    private bool visible = true;
    private readonly List<ToolStripItem> controls;

    protected ToolStripItemCommand()
    {
        controls = new List<ToolStripItem>();
    }

    public void RegisterControl(ToolStripItem item, string eventName)
    {
        item.Click += delegate { Execute(); };
        controls.Add(item);
    }

    public bool Enabled
    {
        get { return enabled; }
        set
        {
            enabled = value;
            foreach (ToolStripItem item in controls)
                item.Enabled = value;
        }
    }

    public bool Visible
    {
        get { return visible; }
        set
        {
            visible = value;
            foreach (ToolStripItem item in controls)
                item.Visible = value;
        }
    }

    protected abstract void Execute();
}

Your implementations of this command can be stateful in order to support your view's state. This also enables the ability to build "undo" into your form. Here's some toy code that consumes this:

private ToolStripItemCommand fooCommand;

private void wireUpCommands()
{
    fooCommand = new HelloWorldCommand();
    fooCommand.RegisterControl(fooToolStripMenuItem, "Click");
    fooCommand.RegisterControl(fooToolStripButton, "Click");            
}

private void toggleEnabledClicked(object sender, EventArgs e)
{
    fooCommand.Enabled = !fooCommand.Enabled;
}

private void toggleVisibleClicked(object sender, EventArgs e)
{
    fooCommand.Visible = !fooCommand.Visible;
}

HelloWorldCommand:

public class HelloWorldCommand : ToolStripItemCommand
{
    #region Overrides of ControlCommand
    protected override void Execute()
    {
        MessageBox.Show("Hello World");
    }
    #endregion
}

It's unfortunate that Control and ToolStripItem do not share a common interface since they both have "Enabled" and "Visible" properties. In order to support both types, you would have to composite a command for both, or use reflection. Both solutions infringe on the elegance afforded by simple inheritance.

Michael Meadows
You never use eventName parameter in RegisterControl method. Is it intended?
Alexander Prokofyev