Dynamically add event handlers to controls in a custom .NET control with C#

A few years back I came up with something called “FRF” (Forms Rendering Framework) which allowed me to render any UI (whether they are Web or Windows based) based on a template definition (Yes, this was long before Microsoft released XAML). Anyways, on one of my personal projects I had a requirement to dynamically create and host Windows controls inside native applications (property pages more specifically). The challenge here was being able to notify the container window (Property page) that something has been modified or changed in the contained user control and then being able to notify the property sheet’s window procedure of that change.  In my personal case, I had to monitor changes made to any textbox (TextChanged) inside the hosted control, the way I got it sorted is depicted below

private IEnumerable<Control> CreateHelper(ITemplateDefinition definition) { var retval = new List<Control>(); var flag = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public; var targetAsm = AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(x => string.Equals(x.GetName().Name, " System.Windows.Forms", StringComparison.OrdinalIgnoreCase)); if (targetAsm != null) { definition.TemplateElements.ToList().ForEach(x => { try { var controlType = targetAsm.GetTypes() .FirstOrDefault(z => z.IsSubclassOf(typeof(Control)) && !z.IsAbstract && z.Name.ToUpperInvariant() .Contains(x.Class.ToUpperInvariant())); // Expected to have a default constructor without any parameters var control = controlType.GetConstructors(flag) .FirstOrDefault().Invoke(null) as Control; PropertySetter(control, x); // Does it have a TextChanged event? var ei = control.GetType().GetEvent("TextChanged"); if (ei != null) ei.AddEventHandler(control, new EventHandler((sender, args) => ChangeMonitor.HasChanges = true)); retval.Add(control); } catch (Exception ex) { Logger.LogError(ex); } }); } return retval; }

Leave a Reply

Your email address will not be published. Required fields are marked *