如何为多个类似的控件编写事件处理程序?

时间:2011-02-08 20:48:03

标签: c# .net winforms events

基本上我有一些控制,他们做类似的事情,但使用不同的值进行不同的控制。例如:

public static void DeleteItemsFromList ( object sender, EventArgs e )
{
    ListBox control = null;
    switch ( ( ( Button ) sender ).Name )
    {
        case "EffectsRemove": control = ( ListBox ) ActiveForm [ "EffectsList" ]; break;
        case "LayersRemove": control = ( ListBox ) ActiveForm [ "LayersList" ]; break;
        case "ObjectsRemove": control = ( ListBox ) ActiveForm [ "ObjectsList" ]; break;
    }

    control.Items.Add ( ( ( Button ) sender ).Name )

    string action = null;
    switch ( ( ( CheckButton ) sender ).Name )
    {
        case "EffectsRemove": action = "Effects"; break;
        case "LayersRemove": action = "Layers"; break;
        case "ObjectsRemove": action = "Objects"; break;
    }

    var selectedItem = control.SelectedItem;
    if ( selectedItem == null )
        return;

    Refresh = false;
    UpdateUI ( action );
    Refresh = true;
}

这是不好的做法吗?有没有更好的方法来基于类似行为的控件来执行这些类型的变量事件处理程序?

4 个答案:

答案 0 :(得分:2)

我个人认为你的例子留下了太多的错误机会。您最好的选择是将常用功能提取到单独的方法中。

public static void EffectsRemove_Click(object sender, EventArgs e)
{
    DeleteItemsFromList(
        (Button)sender, 
        (ListBox)ActiveForm["EffectsList"], 
        "Effects");
}

public static void LayersRemove_Click(object sender, EventArgs e)
{
    DeleteItemsFromList(
        (Button)sender, 
        (ListBox)ActiveForm["LayersList"], 
        "Layers");
}

public static void ObjectsRemove_Click(object sender, EventArgs e)
{
    DeleteItemsFromList(
        (Button)sender, 
        (ListBox)ActiveForm["ObjectsList"], 
        "Objects");
}

public static void DeleteItemsFromList(
    Button sender, 
    ListBox control, 
    string action)
{
    control.Items.Add(sender.Name);

    var selectedItem = control.SelectedItem;
    if ( selectedItem == null )
        return;

    Refresh = false;
    UpdateUI action;
    Refresh = true;
}

答案 1 :(得分:1)

我可以看到你想要重用逻辑的愿望,但在我看来,这种代码使得代码更加脆弱和难以维护,在这种情况下我甚至可能喜欢单独的处理程序,即使代码是伪的 - 类似。

答案 2 :(得分:1)

这是您可以通过订阅EventHandler时定义的一些委托使用的另一种方法。我认为这种方式更容易阅读,但如果添加了其他几个条件(如RichTextBox,如果是Combobox等),可能会失控。

    private void Form1_Load(object sender, EventArgs e)
    {
        button1.Click += new EventHandler(delegate { DoButtonProcessing(this, "EffectsList", null); });
        button2.Click += new EventHandler(delegate { DoButtonProcessing(this, "LayersList", null); });

        button3.Click += new EventHandler(delegate { DoButtonProcessing(this, null, "Effects"); });
        button4.Click += new EventHandler(delegate { DoButtonProcessing(this, null, "Layers"); });
    }

    void DoButtonProcessing(object sender, string list, string action)
    {
        ListBox control = (ListBox)ActiveForm[list]; //can be null here, but your source also allowed that so I assume it's just a snippit.
        control.Items.Add(((Button)sender).Name);
        var selectedItem = control.SelectedItem;
        if (selectedItem == null) return;
        Refresh = false;
        UpdateUI null;
        Refresh = true;

    }

答案 3 :(得分:1)

您可能需要考虑使用自定义控件,您可以从Button派生,并为CustomButton的每个实例添加一些属性,表示您关心的字符串和ListBox。然后你可以将每个按钮绑定到同一个事件处理程序,并对CustomButton的属性进行操作,而不关心它是哪一个。