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

时间:2021-02-17 12:47:21

Basically I have certain controls where they do similar things but for different controls using different values. For instance:

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

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;
}

Is this bad practice? Is there a better way to do these kinds of variable event handlers based on similarly behaving controls?

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

4 个解决方案

#1


2  

Personally I find your example leaves too many opportunities for error. Your best bet would be to extract the common functionality to a separate method.

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

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;
}

#2


1  

I can see your desire to want to reuse logic, but it seems to me this kind of makes the code more brittle and harder to maintain, I'd probably favor separate even handlers in this case even if the code is pseudo-similar.

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

#3


1  

Here's another approach you could use via some delegates defined while subscribing to the EventHandler. I think it's a bit easier to read this way, but could get out of hand if you added several other conditions (like if RichTextBox, if Combobox, etc.)

这是您在订阅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;

    }

#4


1  

You may want to consider using a custom control, where you can derive from Button, and add a few properties to each instance of your CustomButton, representing the string and ListBox that you care about. Then you can tie each button to the same event handler, and act on the properties of the CustomButton, without caring about which one it is.

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

#1


2  

Personally I find your example leaves too many opportunities for error. Your best bet would be to extract the common functionality to a separate method.

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

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;
}

#2


1  

I can see your desire to want to reuse logic, but it seems to me this kind of makes the code more brittle and harder to maintain, I'd probably favor separate even handlers in this case even if the code is pseudo-similar.

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

#3


1  

Here's another approach you could use via some delegates defined while subscribing to the EventHandler. I think it's a bit easier to read this way, but could get out of hand if you added several other conditions (like if RichTextBox, if Combobox, etc.)

这是您在订阅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;

    }

#4


1  

You may want to consider using a custom control, where you can derive from Button, and add a few properties to each instance of your CustomButton, representing the string and ListBox that you care about. Then you can tie each button to the same event handler, and act on the properties of the CustomButton, without caring about which one it is.

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