|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace FormEventsTests
{
public partial class FormSettings : Form
{
Action<object, EventArgs> changeTitleDelegate;
Action<object, EventArgs> displayPropsDelegate;
IList<Person> people;
public FormSettings ( Action<object, EventArgs> ChangeTitleDelegate )
{
this.changeTitleDelegate = ChangeTitleDelegate;
InitializeComponent ( );
// we only need 2 event subscription
uxSetTitle.Click += new EventHandler ( uxSetTitle_Click );
// this form of event we won't need to unsubscribe
uxCloseSettings.Click += delegate { this.Close ( ); };
}
// evolve how we handle events
/* Use an interface to loosely couple to events
*
* Problem for developers, especially GUI devs, is to remember to
* unsubscribe from all events. Even passing a reference to the Owning
* object exposes more risks. Limit the risks involved by exposing
* event handlers, or worse, the entire Owning object.
*
* By interfacing our events, we expose ONLY the Actions. This can
* be thought of as a default action should a certain event occur. Each
* implementation would be fairly custom, but the pattern will be
* recognizable. Loosely coupled events will also make it easier to avoid
* what I call, 'functionCreep(this)'.
*
* functionCreep(this) is when you pass an OwnerObject reference to a child
* or sibling class. What happens is you start executing functions intimate
* to the OwningObject. functionCreep(this) invites exposure of the
* OwningObject's resources.
*
*/
public FormSettings ( IEventPublisher EventOwner )
{
// couple to events
changeTitleDelegate = EventOwner.ChangeFormTitle;
displayPropsDelegate = EventOwner.DisplayProperties;
InitializeComponent ( );
fillPersonSelector ( );
uxSetTitle.Click += new EventHandler ( uxSetTitle_Click );
uxCloseSettings.Click += delegate { this.Close ( ); };
// subscribe
uxPersonSelector.SelectedValueChanged +=
new EventHandler ( uxPersonSelector_SelectedValueChanged );
}
private void fillPersonSelector ( )
{
// get some test data
people = new List<Person>
{
new Person("David", "Silver City", "TX"),
new Person("James", "Houston", "TX"),
new Person("Mandy", "Waco", "TX"),
new Person("Steven", "Santa Fe", "NM"),
new Person("Tina", "Edmond", "OK"),
new Person("Karlena", "Misson", "KS")
};
uxPersonSelector.DisplayMember = "Name";
uxPersonSelector.DataSource = people;
}
void uxSetTitle_Click ( object sender, EventArgs e )
{
// pre-process if necessary
// invoke delegate
this.changeTitleDelegate ( this,
new GenericEventArgs<string> ( uxFormTitle.Text ) );
}
void uxPersonSelector_SelectedValueChanged ( object sender, EventArgs e )
{
// invoke delegate
this.displayPropsDelegate ( this,
new GenericEventArgs<Person> ( (Person)uxPersonSelector.SelectedValue ) );
}
}
public class Person
{
public Person ( string Name, string City, string State )
{
this.City = City;
this.Name = Name;
this.State = State;
}
public string City { get; set; }
public string Name { get; set; }
public string State { get; set; }
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Born and raised in Texas. I have been involved in programming since the early days of the Apple II - AppleSoft Basic and assembly were the two languages back then. Since then, I have watched technology evolve; I have watched the languages evolve. Over the last 5 years, I have been programming in .Net, specifically C#.
I am currently employed as a software engineer in San Diego, CA.