Welcome to Bangladesh Microsoft Technology Community Sign in | Join | Help

Introducing new UIProperty in SmartCodeGenerator

The current downloads upto CTP2.0 ships with only 4 UIProperty for the .Net types (int, string, boolean and ScSqlTablesProperty) but it is very easy to introduce your own UIProperty for any .Net Types.

Lets jump into writing one:

UIProperty: UIProperty is User Interface that is automatically generated in the web page during the Template Generation process. When you declare a property in TheProperties class a User interface to collect data from the user is automatically generated for you. For example if you declare a string property in the "TheProperties" class you will get a UI to capture userinput when you run the application. Here I declared TestProperty and assigned a default value.

public class TheProperties
{
  public TheProperties( )
  {  
    //Please Assign Default Values here
    this.testproperty = "Insert some string."
  }
  //Please Define you Properties below

  private string testproperty;

  public string TestProperty
  {
    get { return testproperty; }
    set { testproperty = value; }
  }

}

When you run your application SmartCodeGenerator Framework check "TheProperties" class and iterates through all its properties and checks if there is a UI available for the .Net Type and generates them in the page.

UIproperty is mapped in the "PropertyAndUIPropertyMaps.xml" file which you will find in your root folder. if you open the file you will see something similiar to this.

<?xml version="1.0"?>
<ArrayOfPropertyTypeAndUIPropertyMap xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<PropertyTypeAndUIPropertyMap>
<PropertyType>System.String</PropertyType>
<PropertyUI>ScStringUIProperty.ascx</PropertyUI>
</PropertyTypeAndUIPropertyMap>

<PropertyTypeAndUIPropertyMap>
<PropertyType>System.Boolean</PropertyType>
<PropertyUI>ScBooleanUIProperty.ascx</PropertyUI>
</PropertyTypeAndUIPropertyMap>

<PropertyTypeAndUIPropertyMap>
<PropertyType>SmartCodeGen.WebUtil.PropTypes.ScSqlTablesProperty</PropertyType>
<PropertyUI>ScSqlTablesUIProperty.ascx</PropertyUI>
</PropertyTypeAndUIPropertyMap>

<PropertyTypeAndUIPropertyMap>
<PropertyType>System.Int32</PropertyType>
<PropertyUI>ScIntegerUIProperty.ascx</PropertyUI>
</PropertyTypeAndUIPropertyMap>

</ArrayOfPropertyTypeAndUIPropertyMap>

Its an array of PropertyTypeAndUIPropertyMap. And if you carefully notice any of the PropertyTypeAndUIPropertyMap node you will figure out a very simple mapping of a fully qualified name of a .Net Type to a ascx usercontrol is performed. ie. the System.String is mapped to ScStringUIProperty.ascx.

Now you might be asking where will the framework find ScStringUIProperty.ascx, open up any of your SmartCodeGenerator Project you will notice there is a Folder named "PropertyControls", the framework looks for the mapped ascx usercontrols here. And should have noticed all the ascx controls that are mapped in the above xml file are all available in this folder.

Lets discuss one of the ascx control (I call them UIProperty Control)....lets do with ScStringUIProperty.ascx.
If you open up this file you will notice this is nothing but a asp.net usercontrol where I have put a Label and a TextBox control. It looks something like this.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ScStringUIProperty.ascx.cs" Inherits="ScStringUIProperty" %>
<table>
<tr>
<td id="prop">
<asp:Label ID="lblPropertyName" runat="server" Text="PropertyName" CssClass="label2"></asp:Label></td>
<td>
<asp:TextBox ID="tbProperty" runat="server"></asp:TextBox></td>
</tr>
</table>

Ok now lets look at the codebehind where we will find the interesting stuff...

First of all notice this usercontrol is inherited from ScUIPropertyBase
public partial class ScStringUIProperty : ScUIPropertyBase
{......

Secondly notice this usercontrol has a second constructor that expects "PropertyInfo" as parameter.

public ScStringUIProperty(PropertyInfo propertyInfo)
{......

Third thing notice that we hook up this control to the event "OnPreGenerate" of the ParentPage

ParentPage.OnPreGenerate += new EventHandler(ScStringUIProperty_OnPreGenerate);

The OnPreGenerate will be called before the template generates so you get a chance to put any codes you wish relevant to this UI before the code generates. Here in this control I did the following.

void ScStringUIProperty_OnPreGenerate(object sender, EventArgs e)
{
  string property = tbProperty.Text;
  if (propertyInfo.CanWrite)
    this.propertyInfo.SetValue(ParentPage.TheProperties, property, null);
}

I checked here whether the propertyInfo canwrite, if true I have set the value of this property to the tbProperty.Text. So whatever the user inputs gets updated in the TheProperties object.

And Finally you should also notice the following part of the constructor where I am grabbing the current value and assigning to the tbProperty.Text

this.propertyInfo = propertyInfo;
if (propertyInfo.CanRead)
{
  object o = propertyInfo.GetValue(ParentPage.TheProperties, null);
  if (o != null)
  {
    tbProperty.Text = o.ToString();
    lblPropertyName.Text = propertyInfo.Name;
  }
}

So when first time when your execute the project the default values that you assigned in your "TheProperties" class (ie. above we have seen we have done [snippet: this.testproperty = "Insert some string.";] ) gets assigned to tbProperty.Text by this line of code [snippet: tbProperty.Text = o.ToString();] and the Label control gets the name of the Property by this line of code [snippet: lblPropertyName.Text = propertyInfo.Name;]

 

In summary its very easy to extend UIProperty

1. Write your ascx file inheriting from ScUIPropertyBase

2. Put this ascx in the "PropertyControl" Folder of your project.

3. Map your ascx filename with the .Net Type in the PropertyAndUIPropertyMaps.xml file

Thats it. You are done and ready to use your new UIPropertyType.
So now we can write any properties for any .Net Types.

Lets write a UIProperty for Mandatory string.

Towrite a mandatory string property we have to do the following:
1. Define a serializable Class ScMandatoryStringProperty.

[Serializable]
public class ScMandatoryStringProperty
{
  private string mandatoryString;

  public string MandatoryString
  {
    get { return mandatoryString; }
    set { mandatoryString = value; }
  }

} 


2. Add a new asp.net usercontrol in the "PropertyControl" Folder (lets call this ScManadatoryStringUIProperty) where we put a Label, Textbox and a asp.net RequiredFieldValidator. Make sure the validator checks the Textbox.


3. In the code behind inherit this ascx from ScUIPropertyBase. And do something like this.

public ScMandatoryStringUIProperty(PropertyInfo propertyInfo)
{
  ParentPage.OnPreGenerate += new EventHandler(ScMandatoryStringUIProperty_OnPreGenerate);
  this.propertyInfo = propertyInfo;
  if (propertyInfo.CanRead)
  {
    object o = propertyInfo.GetValue(ParentPage.TheProperties, null);
    if (o!= null)
      mandatoryStringTextbox.Text = ((ScMandatoryStringProperty)o).MandatoryString;
      lblPropertyName.Text = propertyInfo.Name;
  }
}

void ScMandatoryStringUIProperty_OnPreGenerate(object sender, EventArgs e)
{
  ScMandatoryStringProperty tprop = new ScMandatoryStringProperty();
  tprop.MandatoryString = mandatoryStringTextbox.Text;
  if (propertyInfo.CanWrite)
  {
    this.propertyInfo.SetValue(ParentPage.TheProperties, tprop, null);
  }
}

4. Map this ascx file to the .NetType like the following and add a new node in the "PropertyAndUIPropertyMaps.xml" file.

<PropertyTypeAndUIPropertyMap>
<PropertyType>MandatoryString</PropertyType>
<PropertyUI>ScMandatoryStringUIProperty.ascx</PropertyUI>
</PropertyTypeAndUIPropertyMap>

We have just created a UI for a mandatory string. and if we go now and define a property in the "TheProperty" class we will see this new UI loaded in the page by the framework and already checking for mandatory fields.

public class TheProperties
{
  public TheProperties( )
  {  
    //Please Assign Default Values here

    ScMandatoryStringProperty msp = new ScMandatoryStringProperty
    msp.MandatoryString = "Insert some string";
    this.testproperty = msp;
  }
  //Please Define you Properties below

  private ScMandatoryStringProperty testproperty;

  public ScMandatoryStringProperty TestMandatoryProperty
  {
    get { return testproperty; }
    set { testproperty = value; }
  }

}

Yes we are done.

If you want to see other examples I would suggest to look at all the 4 UIProperty Controls available in the "propetycontrols" folder that ships with CTP2.0 download.

Goodluck on your next UIProperty and please share your UIProperties with the community.
In future posts I ll discuss more on the internals and total architecture of SmartCodeGenerator.

Shahed Khan

Published Saturday, December 02, 2006 2:40 AM by Shahed

Comments

No Comments

Anonymous comments are disabled