banner



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

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel