Click here to Skip to main content
15,886,110 members
Articles / Programming Languages / C#

An XML- and State Machine-based Design of a WinForms Control

Rate me:
Please Sign up or sign in to vote.
4.98/5 (35 votes)
1 Dec 20024 min read 86.1K   1.3K   49  
Usage of state machine and comprehensive XML description of control helps its user to considerably simplify control handling code.
<!--------------------------------------------------------------------------->  
<!--                           INTRODUCTION                                

 The Code Project article submission template (HTML version)

Using this template will help us post your article sooner. To use, just 
follow the 3 easy steps below:
 
     1. Fill in the article description details
     2. Add links to your images and downloads
     3. Include the main article text

That's all there is to it! All formatting will be done by our submission
scripts and style sheets. 

-->  
<!--------------------------------------------------------------------------->  
<!--                        IGNORE THIS SECTION                            -->
<html>
<head>
<title>The Code Project</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<Style>
BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt }
h2, h3, h4, h5 { color: #ff9900; font-weight: bold; }
H2 { font-size: 13pt; }
H3 { font-size: 12pt; }
H4 { font-size: 10pt; color: black; }
PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; }
CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }
</style>
<link rel="stylesheet" type=text/css href="http://www.codeproject.com/styles/global.css">
</head>
<body bgcolor="#FFFFFF" color=#000000>
<!--------------------------------------------------------------------------->  


<!-------------------------------     STEP 1      --------------------------->
<!--  Fill in the details (CodeProject will reformat this section for you) -->


<p>This file is intended to serve as an appendix to an article &quot;An XML- and State Machine-based Design of a WinForms Control&quot;.</p>


<H2>State Machine Related Matrices </H2>

<p>
The control contains set of elements. Each of them has several distinct states. Vector of
elements' states forms the state of entire control. This relationship is represented
by the Control States Matrix.
</p>

<p><u>
Control States Matrix definition
</u></p>

<TABLE borderColor=white cellSpacing=0 width="500" border=0>
	<TBODY>
        	<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>Control's State</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgreen width="73" />
				<TD Align=center vAlign=top bgcolor=lightgreen width="63" />
				<TD Align=center vAlign=top bgcolor=lightgreen width="57" />
				<TD Align=center vAlign=top bgcolor=lightgreen width="70"><B>Element</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgreen width="77" />
				<TD Align=center vAlign=top bgcolor=lightgreen width="81" />
			</TR>
        	<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65" />
				<TD Align=center vAlign=top bgcolor=lightgreen width="73"><B>0</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgreen width="63"><B>1</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgreen width="57"><B>...</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgreen width="70"><B><i>n</i></B></TD>
				<TD Align=center vAlign=top bgcolor=lightgreen width="77"><B>...</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgreen width="81"><B>N-1</B></TD>
			</TR>
			<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>0</B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="73"><B><i>Element's</i></B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="63"><B><i>State</i></B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="57" />
				<TD Align=center vAlign=top bgcolor=lightblue width="70">|</TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="77" />
				<TD Align=center vAlign=top bgcolor=lightblue width="81" />
			</TR>
			<TR>
        		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>1</B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="73" />
				<TD Align=center vAlign=top bgcolor=lightblue width="63" />
				<TD Align=center vAlign=top bgcolor=lightblue width="57" />
				<TD Align=center vAlign=top bgcolor=lightblue width="70">|</TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="77" />
				<TD Align=center vAlign=top bgcolor=lightblue width="81" />
			</TR>
			<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>...</B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="73" />			
				<TD Align=center vAlign=top bgcolor=lightblue width="63" />
				<TD Align=center vAlign=top bgcolor=lightblue width="57" />
				<TD Align=center vAlign=top bgcolor=lightblue width="70">V</TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="77" />
				<TD Align=center vAlign=top bgcolor=lightblue width="81" />
			</TR>
			<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B><i>k</i></B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="73"><B>----------</B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="63"><B>
                ---------</B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="57"><B>------></B></TD>
				<TD Align=center vAlign=top bgcolor=white width="70"><B>
										<i>	
											<span style='color:red'>
												<span style='font-size:12.0pt'>m</span>
												<span style='font-size:8.0pt'>n</span>
											</span>
										</i>			
								</B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="77" />
				<TD Align=center vAlign=top bgcolor=lightblue width="81" />
			</TR>
			<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>...</B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="73" />			
				<TD Align=center vAlign=top bgcolor=lightblue width="63" />
				<TD Align=center vAlign=top bgcolor=lightblue width="57" />
				<TD Align=center vAlign=top bgcolor=lightblue width="70" />
				<TD Align=center vAlign=top bgcolor=lightblue width="77" />
				<TD Align=center vAlign=top bgcolor=lightblue width="81" />
			</TR>
			<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>K-1</B></TD>
				<TD Align=center vAlign=top bgcolor=lightblue width="73" />
				<TD Align=center vAlign=top bgcolor=lightblue width="63" />
				<TD Align=center vAlign=top bgcolor=lightblue width="57" />
				<TD Align=center vAlign=top bgcolor=lightblue width="70" />
				<TD Align=center vAlign=top bgcolor=lightblue width="77" />
				<TD Align=center vAlign=top bgcolor=lightblue width="81" />
			</TR>
	</TBODY>
</TABLE>

<p>
To describe the matrix, let�s assume that the control has <i>N</i> elements numbered
from <i>0</i> to <i>N-1</i>. <i>n</i>-th element has <i>M<span style='font-size:8.0pt'>n</span></i>
states (from <i>0</i> to <i>M<span style='font-size:8.0pt'>n</span>-1</i>). Let�s define state <i>k</i> of the
entire control as a vector of <i>m<span style='font-size:8.0pt'>n</span>
</i>states (<i>n</i>-th�
element in its <i>m</i>-th state). Assuming that control has <i>K</i>
distinct states we get Control States Matrix with <i>K</i> rows (control�s
states) and <i>N</i> columns (elements). Value <i>m<span 
style='font-size:8.0pt'>n </span></i>of matrix [<i>k, n</i>] cell shows that if the control is in the <i>k</i>-th
state then its<i> n</i>-th element is in its <i>m</i>-th state. Value of [<i>k,
n</i>] cell equaled to <i>-1</i> means that any state of <i>n</i>-th element is
�acceptable� for the control's<i> k</i>-th state. Value of all cells of the matrix is
set by default to <i>-1</i>. Values of specific cells (deferred from <i>-1</i>)
are given in XML configuration file.
</p>

<p>
Rules for transition from one control's state to another are defined by the State
Transition Matrices. Such a matrix should be assigned to each element. The 
matrices are in
configuration file. They have also <i>K</i> rows corresponding to the
control's states. But their columns represent possible variants to change element's state.
</p>

<p><u>
State Transition Matrix definition
</u></p>

<TABLE borderColor=white cellSpacing=0 width="500" border=0>
	<TBODY>
        	<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>Control's State</B></TD>
          		<TD Align=center vAlign=top bgcolor=lightgrey width="6"></TD>
				<TD Align=center vAlign=top bgcolor=lightgrey width="66" />
				<TD Align=center vAlign=top bgcolor=lightgrey width="65"><B>Variants</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgrey width="58"><B>to</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgrey width="66"><B>Change</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgrey width="98"><B>Elenment's</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgrey width="60"><B>State</B></TD>
			</TR>
        	<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65" />
				<TD Align=center vAlign=top bgcolor=lightgrey width="6" />
				&nbsp;<TD Align=center vAlign=top bgcolor=lightgrey width="66"><B>0</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgrey width="65"><B>1</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgrey width="58"><B>...</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgrey width="66"><B><i>z</i></B></TD>
				<TD Align=center vAlign=top bgcolor=lightgrey width="98"><B>...</B></TD>
				<TD Align=center vAlign=top bgcolor=lightgrey width="60"><B>Z-1</B></TD>
			</TR>
			<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65" ><B>0</B></TD>
          		<TD Align=center vAlign=top bgcolor=brownwidth="1" width="6"></TD>
				<TD Align=center vAlign=top bgcolor=yellow width="66"><B><i>Control's</i></B></TD>
				<TD Align=center vAlign=top bgcolor=yellow width="65"><B><i>State</i></B></TD>
				<TD Align=center vAlign=top bgcolor=yellow width="58" />
				<TD Align=center vAlign=top bgcolor=yellow width="66">|</TD>
				<TD Align=center vAlign=top bgcolor=yellow width="98" />
				<TD Align=center vAlign=top bgcolor=yellow width="60" />
			</TR>
			<TR>
        		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>1</B></TD>
        		<TD Align=center vAlign=top bgcolor=brownwidth="1" width="6"></TD>
				<TD Align=center vAlign=top bgcolor=yellow width="66" />
				<TD Align=center vAlign=top bgcolor=yellow width="65" />
				<TD Align=center vAlign=top bgcolor=yellow width="58" />
				<TD Align=center vAlign=top bgcolor=yellow width="66">|</TD>
				<TD Align=center vAlign=top bgcolor=yellow width="98" />
				<TD Align=center vAlign=top bgcolor=yellow width="60" />
			</TR>
			<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>...</B></TD>
          		<TD Align=center vAlign=top bgcolor=brownwidth="1" width="6"></TD>
				<TD Align=center vAlign=top bgcolor=yellow width="66" />			
				<TD Align=center vAlign=top bgcolor=yellow width="65" />
				<TD Align=center vAlign=top bgcolor=yellow width="58" />
				<TD Align=center vAlign=top bgcolor=yellow width="66">V</TD>
				<TD Align=center vAlign=top bgcolor=yellow width="98" />
				<TD Align=center vAlign=top bgcolor=yellow width="60" />
			</TR>
			<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B><i>k</i></B></TD>
          		<TD Align=center vAlign=top bgcolor=brownwidth="1" width="6">&nbsp;</TD>
				<TD Align=center vAlign=top bgcolor=yellow width="66"><B>---------</B></TD>
				<TD Align=center vAlign=top bgcolor=yellow width="65"><B>---------</B></TD>
				<TD Align=center vAlign=top bgcolor=yellow width="58"><B>------></B></TD>
				<TD Align=center vAlign=top bgcolor=white width="66"><B>
										<i>	
											<span style='color:red'>
												<span style='font-size:12.0pt'>k</span>
												<span style='font-size:8.0pt'>new</span>
											</span>
										</i>			
								</B></TD>
				<TD Align=center vAlign=top bgcolor=yellow width="98" />
				<TD Align=center vAlign=top bgcolor=yellow width="60" />
			</TR>
			<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>...</B></TD>
          		<TD Align=center vAlign=top bgcolor=brownwidth="1" width="6"></TD>
				<TD Align=center vAlign=top bgcolor=yellow width="66" />			
				<TD Align=center vAlign=top bgcolor=yellow width="65" />
				<TD Align=center vAlign=top bgcolor=yellow width="58" />
				<TD Align=center vAlign=top bgcolor=yellow width="66" />
				<TD Align=center vAlign=top bgcolor=yellow width="98" />
				<TD Align=center vAlign=top bgcolor=yellow width="60" />
			</TR>
			<TR>
          		<TD Align=center vAlign=top bgcolor=yellow width="65"><B>K-1</B></TD>
          		<TD Align=center vAlign=top bgcolor=brownwidth="1" width="6"></TD>
				<TD Align=center vAlign=top bgcolor=yellow width="66" />
				<TD Align=center vAlign=top bgcolor=yellow width="65" />
				<TD Align=center vAlign=top bgcolor=yellow width="58" />
				<TD Align=center vAlign=top bgcolor=yellow width="66" />
				<TD Align=center vAlign=top bgcolor=yellow width="98" />
				<TD Align=center vAlign=top bgcolor=yellow width="60" />
			</TR>
	</TBODY>
</TABLE>

<p>
For example, for <code>OGCVisualElement</code> there is only one possible variant to change its state
� being clicked. So, for this type of element State Transition Matrix is reduced
to vector. The <i>k</i>-th coordinate of this vector equaled to <i>k<span
style='font-size:8.0pt'>new</span></i> means that if this element is
clicked when control is in the<i> k</i>-th state then the control will transit to 
its <i>k<span
style='font-size:8.0pt'>new</span></i>-th state.
</p>

<p>
On the other hand, <code>OGCComboBox</code> element with <i>Z</i> strings in the list has <i>Z</i>
possible variants to change its state (select any of the strings). So, <code>OGCComboBox</code>
element is characterized with [<i>K <span style='font-size:8.0pt'>*</span> Z</i>] State Transition Matrix. [<i>k, z</i>]-th
cell of this matrix equaled to <i>k</i><i><span style='font-size:8.0pt'>new</span></i>
means that if the <i>z</i>-th string is selected in combo box when the control is in <i>k</i>-th
state then the control will transit to the <i>k</i><i><span style='font-size:8.0pt'>new</span></i>-th
state.
</p>

<p>
<i>k<span style='font-size:8.0pt'>new</span></i> equaled to <i>-1</i> indicates that no
change in the control's state will be made in response to this action (i.e., <i>k<span
style='font-size:8.0pt'>new</span> = k</i>, but it is easier to assign a uniform 
value -1 by default). Value of all cells of the
matrix (vector) is set by default to <i>-1</i>. Values of specific cells (deferred
from <i>-1</i>) are given in XML configuration file.
</p>


<H2>Error Handling</H2>

<p>
Error handling mechanism is chiefly located in <code>OGControl</code> class. The <code>ErrorEvent</code> is generated
when error occurs. An instance of <code>ErrorEventArgs</code> class containing error�s severity
and message is sent as a parameter to the delegate implementation. Error
message templates are read from <i>OGCErrorMessages.xml</i> file by <code>Configurator</code> and
added to appropriate list in <code>OGControl</code>. Message templates are listed in <i>OGCErrorMessages.xml</i>
file.</p>


<H2>Docking</H2>

<p dir="ltr">
The docking position of the control is changed by dragging the control with its
caption.  Position of an element within control may be specified (in XML 
configuration file) differently for cases of horizontal (docked to top, bottom 
or fill) and vertical (docked to left or right) orientation of the control. Images also rotate on 
<i>+</i>
or <i>� 90</i> degrees when orientation changes if <i>Rotate</i> value of the <i>OGControl</i>
tag in XML configuration file is set to <i>�Yes�</i>.</p>


<H2>Sample Description</H2>

<p>The sample presents a WinForm containing two open group controls, namely, the Toggle 
and the Map. The Toggle control with just one hot spot element has two states. 
Depending on a current Toggle's state parent forms shows or hides the Map 
control. The Toggle control is configured with the <i>Config_Toggle.xml</i> 
file. For this control the <i>Rotate</i> property is initially set to &quot;<i>Yes</i>&quot;. 
Thus, orientation of its hot spot element changes when control's orientation 
changes due to docking. The Map control depicts map of three Baltic states and 
related combo box(es). In Example 1 each state may be selected either by click 
on its territory or by appropriate selection in country combo box. In Examlpe 2 
not only the state but also weather may be selected. Files <i>Config_Map.xml</i> 
and <i>Config_Map_WithWeather.xml</i> configure the Map control for the two 
examples. Appropriate Control States and State Transition matrices and vectors 
may be learned from these files (for both examples Control States matrices in 
conventional form are also presented in the <i>Matrices_to_Examples.txt </i>file). 
Cells with default <i>-1</i> values are omitted in the configuration files and 
also in the <i>Matrices_to_Examples.txt</i> file. </p>

<p dir="ltr">In Example 1 the Control States Matrix has no default value (except 
for the <i>0</i>-th element column, but this element has only one state anyway). It means 
that each control's state strictly defines state of each element. In Example2 
control deals with two separate tasks (selection of a state and selection of weather). This 
leads to presence of default <i>-1</i> values in Control States Matrix, and, therefore, to uncertainity: 
e.g., for one selected state all kinds of weather may be selected. 
So, it is not possible to save (say, for the next application run) exact state of all 
elements using the Control States Matrix alone. If such a necessity exists then 
special measures should be taken (like saving elements' states explicitly - 
this is not done in sample presented). </p>

<p dir="ltr">In Example 2 strict control's states definition leads to 
considerable increase in their number (multiplication of possibilities numbers 
for all tasks). This consideration should be taken into account while design and 
use control.</p>

<p dir="ltr"><b><font size="2">Pictures Sources.&nbsp; </font></b>Map picture 
was taken from 
<a href="http://www.agentura.ru/opponent/baltia/map.jpg">here</a>. Weather pictures were copied from the CNN weather site 
and undergone some modifications.</p>

<p dir="ltr">&nbsp;</p>

<!-------------------------------    That's it!   --------------------------->
</body>
</html>

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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
Israel Israel


  • Nov 2010: Code Project Contests - Windows Azure Apps - Winner
  • Feb 2011: Code Project Contests - Windows Azure Apps - Grand Prize Winner



Comments and Discussions