I want to duplicate a control like a Button, TextBox, etc.
But I don't know how I can copy event handler methods (like Click
) to the new control.
I have the following code now:
var btn2 = new Button();
btn2.Text = btn1.Text;
btn2.size = btn1.size;
// ...
btn2.Click ??? btn1.Click
Is there any other way to duplicate a control?
Now, press the button named “Copy event handlers” and enter some text in the textbox labeled Destination. If all goes well, you should see the messages from the event handlers attached to the Source textbox now attached to the Destination textbox. For copying handlers from one control to another, you just need those two lines of code:
Sharing the same event handler method shouldn't be a problem - it's the BackgroundWorker which provides the "e" in which you store the result. On the other hand, you are accessing resultArray from multiple threads. That could be causing a problem.
All workers are sharing the same event handler which does same thing only with different argument and result like this:
For instance, the property Events is marked as protected in the Control class and there isn't another way to access it (unless you are using extended controls or the like, but this isn’t our case). The current implementation only works with events declared on the Control class.
To clone all events of any WinForms control:
var eventsField = typeof(Component).GetField("events", BindingFlags.NonPublic | BindingFlags.Instance);
var eventHandlerList = eventsField.GetValue(button1);
eventsField.SetValue(button2, eventHandlerList);
You just need to add the event handler method for the new button control. C# uses the +=
operator to do this. So you could simply write:
btn2.Click += btn1_Click
Alternatively, a somewhat more powerful approach is to use reflection. Of particular use here would be the EventInfo.AddEventHandler
method.
If you're simply looking to duplicate the HTML element that will eventually render (including attached event handlers), you can use below extension method to output a copy of the HTML.
/// <summary>
/// Render Control to HTML as string
/// </summary>
public static string Render(this System.Web.UI.Control control)
{
var sb = new StringBuilder();
System.IO.StringWriter stWriter = new System.IO.StringWriter(sb);
System.Web.UI.HtmlTextWriter htmlWriter = new System.Web.UI.HtmlTextWriter(stWriter);
control.RenderControl(htmlWriter);
return sb.ToString();
}
Then you can use it to out put a copy in the aspx markup like this:
<%= btn1.Render() %>
If you want to modify, say, the text on the copy, you could do a string Replace on the Rendered html, or you could set the Text on the original button, and reset it after the Render
call in the asx, i.e.:
<% btn1.Text = "Text for original button"; %>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With