|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionEveryone who has worked with Borland's Delphi knows how powerful Actions are. Actions are used to link together various UI elements, such as buttons, menu items, and toolbar buttons, making them behave consistently: linked items are checked/ unchecked/ enabled/ disabled at the same time, and they share the same Using the codeThis library is based on two main components: the
After adding and setting the desired values for the Action's properties, you can link it to a control, and you'll notice how its property values like
Each Action exposes two main events: How actions work behind the scenesI'm not going to explain every line of code: if you've got a little experience with the .NET Framework, everything is pretty simple and easy to understand, so I'll focus only on a couple of main topics. First of all, every Action internally holds a collection of target controls. Once a control is added, its properties are refreshed according to the Action's ones, and its internal void InternalAddTarget(Component extendee)
{
// we first add extendee to targets collection
targets.Add(extendee);
// we refresh its properties to Action's ones
refreshState(extendee);
// we add some handler to its events
AddHandler(extendee);
OnAddingTarget(extendee);
}
Let's first take a look on how the target's property setting is handled: all the work is performed by the private private void updateProperty(Component target, string propertyName, object value)
{
WorkingState = ActionWorkingState.Driving;
try
{
if (ActionList != null)
{
if (!SpecialUpdateProperty(target, propertyName, value))
ActionList.TypesDescription[target.GetType()].SetValue(
propertyName, target, value);
}
}
finally
{
WorkingState = ActionWorkingState.Listening;
}
}
As a first step, it changes the Action's working state to About event handling: when a control is added to the target's collection, the Action traps its protected virtual void AddHandler(Component extendee)
{
// Click event's handling, if present
EventInfo clickEvent = extendee.GetType().GetEvent("Click");
if (clickEvent != null)
{
clickEvent.AddEventHandler(extendee, clickEventHandler);
}
// CheckStateChanged event's handling, if present
EventInfo checkStateChangedEvent =
extendee.GetType().GetEvent("CheckStateChanged");
if (checkStateChangedEvent != null)
{
checkStateChangedEvent.AddEventHandler(extendee,
checkStateChangedEventHandler);
}
}
private void handleClick(object sender, EventArgs e)
{
if (WorkingState == ActionWorkingState.Listening)
{
Component target = sender as Component;
Debug.Assert(target != null, "Target is not a component");
Debug.Assert(targets.Contains(target),
"Target doesn't exist on targets collection");
DoExecute();
}
}
private void handleCheckStateChanged(object sender, EventArgs e)
{
if (WorkingState == ActionWorkingState.Listening)
{
Component target = sender as Component;
CheckState = (CheckState)ActionList.
TypesDescription[sender.GetType()].GetValue("CheckState", sender);
}
}
The last point to explain is how the void Application_Idle(object sender, EventArgs e)
{
OnUpdate(EventArgs.Empty);
}
public event EventHandler Update;
protected virtual void OnUpdate(EventArgs eventArgs)
{
// we first raise ActionList's Update event
if (Update != null)
Update(this, eventArgs);
// next, we raise child actions update
foreach (Action action in actions)
{
action.DoUpdate();
}
}
How to create your own custom actionBy version 1.1.1.0, Crad's Actions library offers a better support to expandability. It's pretty easy to build your own custom Action: all you have to do is to create a new class which inherits from This behaviour is achieved by the private Type[] getReturnedTypes(IServiceProvider provider)
{
List<Type> res = new List<Type>();
ITypeDiscoveryService tds = (ITypeDiscoveryService)
provider.GetService(typeof(ITypeDiscoveryService));
if (tds != null)
foreach (Type actionType in tds.GetTypes(typeof(Action), false))
{
if (actionType.GetCustomAttributes(typeof(
StandardActionAttribute), false).Length > 0 &&
!res.Contains(actionType))
res.Add(actionType);
}
return res.ToArray();
}
First of all, it recovers a reference to the designer's Points of interestActions can help a Windows Forms developer to coordinate the behaviour of various UI elements in a pretty simple and efficient way. I wanted them be linkable to a lot of .NET Framework 2.0 WinForms controls (they work with every Crad's Actions library ships with some purpose-specific actions too: for example, some of them are helpful to handle clipboard-related operations, such as cut, copy, or paste, while others provide formatting features when applied to a To better understand how easy it is to implement complex user interfaces using Actions, you can check out the simple RTF Editor provided as a demo application. History
|
||||||||||||||||||||||