Reputation: 330872
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?
Upvotes: 1
Views: 1613
Reputation: 40383
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.
Upvotes: 1
Reputation: 13196
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.)
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;
}
Upvotes: 1
Reputation: 78252
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;
}
Upvotes: 2
Reputation: 38397
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.
Upvotes: 1