How Do I Add Dynamic Event On Dynmaic Button C#
Problem
Y'all want to be able to build up an object to work with on the fly at runtime.
Solution
Utilize ExpandoObject
to create an object that you can add properties, methods, and events to and be able to data bind to in a user interface.
Learn faster. Dig deeper. Meet farther.
We can use ExpandoObject
to create an initial object to hold the Name
and electric current Country
of a person.
dynamic expando = new ExpandoObject(); expando.Proper name = "Brian"; expando.Country = "United states of america";
Once we have added properties directly, we can too add backdrop to our object in a more than dynamic fashion using the AddProperty
method we have provided for y'all. One example of why you might do this is to add properties to your object from another source of data. We will add the Language
holding.
// Add together backdrop dynamically to expando AddProperty(expando, "Language", "English");
The AddProperty
method takes advantage of the support that ExpandoObject
has for IDictionary<string, object>
and allows u.s. to add properties using values we decide at runtime.
public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue) { // ExpandoObject supports IDictionary so nosotros tin extend information technology like this var expandoDict = expando as IDictionary<string, object>; if (expandoDict.ContainsKey(propertyName)) expandoDict[propertyName] = propertyValue; else expandoDict.Add(propertyName, propertyValue); }
We can besides add methods to the ExpandoObject
by using the Func<>
generic type which represents a method telephone call. In our example, we will add a validation method for our object:
// Add method to expando expando.IsValid = (Func<bool>)(() => { // Check that they supplied a name if(string.IsNullOrWhiteSpace(expando.Proper name)) return fake; return true; }); if(!expando.IsValid()) { // Don't allow continuation... }
Now we can also define and add together events to the ExpandoObject
using the Action<>
generic type. Nosotros volition add together ii events, LanguageChanged
and CountryChanged
. LanguageChanged
will exist added later on defining the eventHandler
variable to concord the Activeness<object,EventArgs>
and CountryChanged
we volition add directly as an inline bearding method. CountryChanged
looks at the Country
that changed and invokes the LanguageChanged
issue with the proper Language
for the Country
. (Note that LanguageChanged is also an anonymous method but sometimes it can make for cleaner code to have a variable for these).
// Y'all can also add event handlers to expando objects var eventHandler = new Action<object, EventArgs>((sender, eventArgs) => { dynamic exp = sender every bit ExpandoObject; var langArgs = eventArgs equally LanguageChangedEventArgs; Console.WriteLine($"Setting Linguistic communication to : {langArgs?.Linguistic communication}"); exp.Language = langArgs?.Language; }); // Add together a LanguageChanged event and predefined event handler AddEvent(expando, "LanguageChanged", eventHandler); // Add a CountryChanged issue and an inline event handler AddEvent(expando, "CountryChanged", new Action<object, EventArgs>((sender, eventArgs) => { dynamic exp = sender as ExpandoObject; var ctryArgs = eventArgs as CountryChangedEventArgs; string newLanguage = string.Empty; switch (ctryArgs?.State) { instance "France": newLanguage = "French"; suspension; case "China": newLanguage = "Mandarin"; break; case "Spain": newLanguage = "Spanish"; break; } Console.WriteLine($"Country changed to {ctryArgs?.Country}, " + $"changing Language to {newLanguage}"); exp?.LanguageChanged(sender, new LanguageChangedEventArgs() { Linguistic communication = newLanguage }); }));
The AddEvent
method we accept provided for you to encapsulate the details of adding the issue to the ExpandoObject
. This again takes advantage of ExpandoObject
's support of IDictionary<string,object>
:
public static void AddEvent(ExpandoObject expando, cord eventName, Action<object, EventArgs> handler) { var expandoDict = expando as IDictionary<string, object>; if (expandoDict.ContainsKey(eventName)) expandoDict[eventName] = handler; else expandoDict.Add together(eventName, handler); }
Finally, ExpandoObject
supports INotifyPropertyChanged
which is the foundation of data bounden to properties in .Net. We claw upward the event handler and when the Country
property is changed, we burn down the CountryChanged
event.
((INotifyPropertyChanged)expando).PropertyChanged += new PropertyChangedEventHandler((sender, ea) => { dynamic exp = sender as dynamic; var pcea = ea equally PropertyChangedEventArgs; if(pcea?.PropertyName == "Country") exp.CountryChanged(exp, new CountryChangedEventArgs() { Land = exp.Country }); });
At present that our object is done being constructed, we can invoke it like this to simulate our friend travelling around the world:
Console.WriteLine($"expando contains: {expando.Name}, {expando.Country}, {expando.Language}"); Console.WriteLine(); Console.WriteLine("Changing Country to France..."); expando.Country = "France"; Console.WriteLine($"expando contains: {expando.Name}, {expando.Country}, {expando.Language}"); Console.WriteLine(); Console.WriteLine("Changing Land to People's republic of china..."); expando.Country = "China"; Panel.WriteLine($"expando contains: {expando.Name}, {expando.Land}, {expando.Language}"); Console.WriteLine(); Console.WriteLine("Changing Country to Spain..."); expando.Country = "Spain"; Console.WriteLine($"expando contains: {expando.Name}, {expando.Country}, {expando.Linguistic communication}"); Panel.WriteLine();
The output of this example is shown here:
expando contains: Brian, USA, English
Changing Country to France... Land inverse to France, irresolute Language to French Setting Language to: French expando contains: Brian, France, French Changing Country to Prc... Country changed to China, changing Language to Mandarin Setting Language to: Standard mandarin expando contains: Brian, Red china, Mandarin Irresolute Country to Kingdom of spain... State changed to Spain, changing Language to Spanish Setting Language to: Spanish expando contains: Brian, Spain, Castilian
Discussion
ExpandoObject
allows you to write code that is more readable than typical reflection lawmaking with GetProperty("Field")
syntax. Information technology can be useful when dealing with XML or JSON for apace setting up a type to program against instead of always having to create information transfer objects. The power for ExpandoObject
to back up data bounden through INotifyPropertyChanged
is a huge win for anyone using WPF, MVC, or any other binding framework in .NET as it allows you lot to apply these "objects on the wing" too as other statically typed classes.
Since ExpandoObject
can accept delegates every bit members, this allows united states to attach methods and events to these dynamic types while the lawmaking looks like y'all are addressing a static type.
public static void AddEvent(ExpandoObject expando, cord eventName, Action<object, EventArgs> handler) { var expandoDict = expando every bit IDictionary<string, object>; if (expandoDict.ContainsKey(eventName)) expandoDict[eventName] = handler; else expandoDict.Add together(eventName, handler); }
For both AddEvent
and AddProperty
, you might be request why didn't we use extension methods for AddProperty
and AddEvent
? They both could hang off of ExpandoObject
and make the syntax fifty-fifty cleaner, correct? Unfortunately, that is non possible as extension methods work past the compiler doing a search on all classes that might be a match for the extended class. This means that the DLR
would have to know all of this information at runtime likewise (since ExpandoObject
is handled past the DLR
) and currently all of that information is non encoded into the call site for the form and methods.
The event statement classes for the LanguageChanged
and CountryChanged
events are listed here:
public class LanguageChangedEventArgs : EventArgs { public string Language { get; ready; } } public grade CountryChangedEventArgs : EventArgs { public string Country { get; set; } }
Encounter Also
See the "ExpandoObject
class","Func<>
consul", "Action<>
consul", and the "INotifyPropertyChanged
interface" in the MSDN documentation.
How Do I Add Dynamic Event On Dynmaic Button C#,
Source: https://www.oreilly.com/content/building-c-objects-dynamically/
Posted by: ramseybroolivies.blogspot.com
0 Response to "How Do I Add Dynamic Event On Dynmaic Button C#"
Post a Comment