|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionMany people think of programming data entry forms as very boring activity. I think so too. But sometimes I feel that something must be done to make this job easier. So I’ve developed this control to simplify designing and programming data entry forms. Data entry forms are associated with documents, and enable the user to perform operations on associated documents, usually, operations such as creating, viewing, editing, and searching of documents. At any given time, a data entry form can be in one of several pre-defined states, depending on the operation that the user is currently performing. While designing a data entry form, the developer defines states which the form will maintain, and programs the logic that sets the form to a particular state in response to the user’s interaction. Say the user selects a menu option or clicks a button to enter a new document. When a form is set to a new state, some of its controls are enabled (become active) to process the user’s input while other controls are disabled. In some cases, programming such logic is not as simple as it seems. We need to take into account such factors as the document status, the user’s privileges and so on to give the user the access to only certain fields on a form. The State Controller provides design-time support for specifying the states for each control on a form in which this control is enabled, and/or states in which the control is visible. The State Controller also provides a method that sets a host form to the specified state at runtime. Using the codeIn order to use this control, while in design mode, you need to install it on the VS toolbox. To do that, select a tab you want to add this control to, right-click somewhere in your toolbox, and select "Add/Remove Items...", then navigate to the location of the StateController.DLL, select the DLL, and click OK. After that the control should be in your toolbox. PropertiesThe control implements the StateActve on StateController1
The control also provides its own properties:
Method
Event
I created a demo project to show how this control can be used. The demo includes a data entry form that maintains the Customer table from the Northwind database. This form supports basic operations on the table – adding, editing, viewing, and searching records. I also wanted to demonstrate how to use this control to permit only users with certain privileges to have access to some fields. In this case, a user with super-user privileges can see the customer balance and edit the value of the Credit Limit field. So I defined the following states for this form:
The form is set to a new state in response to user interaction. The Points of interestThe control is a subclass of the [ToolboxBitmap(typeof(StateController))]
[ProvideProperty("StateActive", typeof(Control)),
ProvideProperty("StateVisible", typeof(Control)),
Designer(typeof(StateControllerDesigner)),
DefaultEvent("StateChanged"),
ToolboxItemFilter("System.Windows.Forms")]
public class StateController : System.ComponentModel.Component,
IExtenderProvider, ISupportInitialize
Two hash tables are used to stash the values of the properties extended for the form’s controls. The reference to a control is used as the key for the hash table entry, and the value of the property is stored in the value part of the hash table entry. The public bool CanExtend(object extendee)
{
return ((extendee is Control) && !(extendee is Form));
}
When implementing The [Description("Retrieve Active States descriptors for a control"),
Category("StateManagment"),Localizable(true),
Editor(typeof(SelectedStatesEditor),
typeof(System.Drawing.Design.UITypeEditor))]
public virtual string GetStateActive(Control ctl)
{
return (string) this.m_activeStates[ctl];
}
public virtual void SetStateActive(Control ctl,string value)
{
if (this.DesignMode)
{
if (value!=null)
{
// remove blanks if any
this.CleanInput(ref value);
if (!CheckValue(value))
// Validate user's input
throw new ArgumentException("Invalid value " +
value);
}
}
if (value!=null)
this.m_activeStates[ctl] = value;
else
this.m_activeStates.Remove(ctl);
}
The pair of methods private bool ShouldSerializeStateActive(Control ctrl)
{
if ((this.m_activeStates[ctrl] == null) || (
((string)this.m_activeStates[ctrl]).Length == 0))
return false;
return true;
}
private void ResetStateActive(Control ctrl)
{
this.SetStateActive(ctrl, "");
}
The The assembly contains the control class itself and auxiliary classes – type converters, UI editors, a control designer which facilitates the design-time behavior of the control, and the serialization of the control’s properties in the form code. Actually, I spent 90% of my time on programming and debugging these editors and converters.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||