One of the more popular posts on my blog here were the Dynamic Forms for Silverlight series I did a couple of years ago. Dynamic forms are useful for cases when you want to compose a form on the server and the client just renders it based on the provided field types.
This days it’s all about Windows Phone 7 so I updated the sample to show how the same technique of creating custom forms on the client can work on the phone as well. The attached project contains both Silverlight and Windows Phone 7 projects, both sharing resources from the same shared project.
Source code for this article is available.
How it works
You compose your fields collection on the server, like in the following snippet:
Collection<DynamicFormField> form = new Collection<DynamicFormField>
{
new DynamicFormField()
{
Caption = "Name: ",
Type = typeof (string).FullName
},
new DynamicFormField()
{
Caption = "Last name: ",
Type = typeof (string).FullName
},
new DynamicFormField()
{
Caption = "Email: ",
Type = "#Email#"
},
new DynamicFormField()
{
Caption = "Phone: ",
Type = "#Phone#"
},
new DynamicFormField()
{
Caption = "Birth date: ",
Type = typeof (DateTime).FullName
},
new DynamicFormField()
{
Caption = "Is employed: ",
Type = typeof (bool).FullName,
Value = false.ToString()
},
new DynamicFormField()
{
Caption = "Signature: ",
Type = "#Signature#"
}
};
The above collection contains:
- Name and Last name fields, which are regular strings (System.String),
- Email and Phone fields, for which we want them to be special kinds of a string so we mark them as “#Email#” and #Phone#,
- Birth date field – a regular Date,
- Is Employed field, that is of type Boolean, and
- Signature field, which will contain an actual written signature, therefore we mark it as "#Signature#-
On the client size, we use the same template selector I used in my previous posts, and templates for the above fields are defined as:
<Shared:FormFieldTemplateSelector DataType="{Binding Type}">
<Shared:FormFieldTemplateSelector.DataTemplates>
<Shared:TemplateSelectorDataTemplate DataType="System.String">
<TextBox Text="{Binding Value, Mode=TwoWay}" Width="400" />
</Shared:TemplateSelectorDataTemplate>
<Shared:TemplateSelectorDataTemplate DataType="#Email#">
<TextBox Text="{Binding Value, Mode=TwoWay}" Width="400"
InputScope="EmailUserName" />
</Shared:TemplateSelectorDataTemplate>
<Shared:TemplateSelectorDataTemplate DataType="#Phone#">
<TextBox Text="{Binding Value, Mode=TwoWay}" Width="400"
InputScope="TelephoneNumber" />
</Shared:TemplateSelectorDataTemplate>
<Shared:TemplateSelectorDataTemplate DataType="System.DateTime">
<Controls:DatePicker Value="{Binding Value, Mode=TwoWay}"
Width="400" />
</Shared:TemplateSelectorDataTemplate>
<Shared:TemplateSelectorDataTemplate DataType="System.Boolean">
<CheckBox IsChecked="{Binding Value, Mode=TwoWay}" />
</Shared:TemplateSelectorDataTemplate>
<Shared:TemplateSelectorDataTemplate DataType="#Signature#">
<Shared:SignaturePanel Width="400" Height="100"
Strokes="{Binding Value, Mode=TwoWay,
Converter={StaticResource strokesConverter}}" />
</Shared:TemplateSelectorDataTemplate>
</Shared:FormFieldTemplateSelector.DataTemplates>
</Shared:FormFieldTemplateSelector>
If you questioned the use of #Email# and #Phone# custom types instead of regular strings, the above snippet should make it clear – those were hints, intended for the (Windows Phone) client, so it can set the right input scopes for those fields.
This is how the form looks after the user fills it up:
Source code is available. Note that it’s only intended for showcasing the specific features and it’s far from production quality. Silverlight Toolkit for Windows Phone 7 (v4.2011.2) binary is not included, but was pulled in through NuGet.
75eff191-93ce-4d14-becb-6f5c76b52c31|1|1.0|27604f05-86ad-47ef-9e05-950bb762570c