HTTP API Enhancements in DBL 10.1
January 14, 2013Using Synergy .NET in Multi-Threaded Applications
October 10, 2013In my previous article (Symphony Framework Basics: Data Binding) I demonstrated how to perform simple data binding between your XAML UI controls and your Data Objects. This article demonstrates how to build powerful styles to define and control your user interface and provide automated data binding to your Data Objects.
Before we look at styles, let’s recap how we do data binding. Consider the following simple repository structure;
Record group_record
GROUP_ID ,A20 ; (1,20) group id
DESCRIPTION ,A100 ; (21,120) description
When created as a Data Object this creates two properties;
public property Group_id, a20
public property Description, a100
In the XAML code we can data bind the properties exposed by the Data Object to standard UI controls;
<TextBox Text=”{Binding Path=Group_id, Converter={StaticResource alphaConverter}}”/>
<TextBox Text=”{Binding Path=Description, Converter={StaticResource alphaConverter}}”/>
There are a number of issues here, and not all of them are obvious. Although we have performed the data binding, there is no code in the XAML to prevent the user typing more characters than the underlying data allows. The Group_id property for example only allows up to twenty characters, so we need to add code to prevent more being entered. In the repository we’ve defined the field to only contain uppercase characters and again the XAML is not honouring this requirement. When a field is in error, for example a required field that is blank, the underlying Data Object exposes this information, but we are not utilising it here. Also, controlling if the field is read-only, if entry is disabled, etc. All these setting and more can be configured against the field in the Synergy Repository.
Using CodeGen and the correct Symphony templates we can generate styles that define exactly how we require field entry to be controlled.
Generating the style files is very simple. The syntax to execute CodeGen with is;
codegen -s GROUP -t Symphony_Style -n GroupMaint -ut ASSEMBLYNAME=GroupMaint -cw 16
One interesting item on the CodeGen command line is the “-cw 16”. This simply defines the standard width as 16 pixels for each character and is used when defining the size of a control.
The generated style file contains individual styles for each field in the repository structure, as well as a style for the prompt. Here is an example of a prompt style;
<Style x:Key=”Group_Group_id_prompt” TargetType=”{x:Type Label}”>
<Setter Property=”Template”>
<Setter.Value>
<ControlTemplate TargetType=”{x:Type Label}”>
<Label
Content=”Group ID”
IsEnabled=”{Binding Path=Group_idIsEnabled}”>
</Label>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And a field style;
<Style x:Key=”Group_Group_id_style” TargetType=”{x:Type symphonyControls:FieldControl}”>
<Setter Property=”FocusVisualStyle” Value=”{x:Null}”/>
<Setter Property=”Focusable” Value=”False”></Setter>
<Setter Property=”Template”>
<Setter.Value>
<ControlTemplate TargetType=”{x:Type symphonyControls:FieldControl}”>
<TextBox Name=”ctlGroup_Group_id”
Text=”{Binding Path=Group_id, Converter={StaticResource alphaConverter},
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True}”
Validation.ErrorTemplate=”{StaticResource validationTemplate}”
MaxLength=”20″
Width=”320″
CharacterCasing=”Upper”
IsEnabled=”{Binding Path=Group_idIsEnabled}”
IsReadOnly=”{Binding Path=Group_idIsReadOnly}”
VerticalAlignment=”Center”
HorizontalAlignment=”Left”
ToolTip=”{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors), Converter={StaticResource errorConveter}}”>
<TextBox.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding=”{Binding Path=Group_idIsFocused}” Value=”true”>
<Setter Property=”FocusManager.FocusedElement”
Value=”{Binding ElementName=ctlGroup_Group_id}”></Setter>
</DataTrigger>
<DataTrigger Binding=”{Binding RelativeSource={RelativeSource Self},Path=(Validation.HasError)}” Value=”True”>
<Setter Property=”TextBox.Background”>
<Setter.Value>
<LinearGradientBrush StartPoint=”0.5,0″ EndPoint=”0.5,1″>
<LinearGradientBrush.GradientStops>
<GradientStop Offset=”0.2″ Color=”WhiteSmoke” />
<GradientStop Offset=”3″ Color=”Red” />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This code may look a little verbose but enables a number of capabilities, including;
- Data binds the underlying UI control to the Data Object property
- Control features like field length, character casing, read-only, etc.
- The Tooltip is used to display any error information if the field is in error.
- The control background colour is made red if the field is in error.
Once you have created your styles and added them to your Visual Studio project you can then reference and use them in your UI design. To reference the style;
<ResourceDictionary Source=”pack:/GroupMaint;component/Resources/Group_style.CodeGen.xaml”/>
Each style is based on a control in the Symphony Framework called “FieldControl” which can be found in the Symphony.Conductor.Controls namespace. You must add a reference to this namespace in your XAML code;
xmlns:symphonyControls=”clr-namespace:Symphony.Conductor.Controls;assembly=SymphonyConductor”
Now you can reference the FieldControl and apply the required style to it;
<symphonyControls:FieldControl DataContext=”{Binding Path=MasterData}”
Style=”{StaticResource Group_Group_id_style}”>
</symphonyControls:FieldControl>
And to add the prompt, or label style use;
<Label Style=”{StaticResource Group_Group_id_prompt}”
DataContext=”{Binding Path=MasterData}” />
Because the styles are linked to the same property in the same Data Object when your code disables the input control the prompt will be greyed out as well.
The code snippets here are just part of the overall solution. This article convers styling of the user interface. The next article will demonstrate using all of the difference Synergy fields types and utilizing controls like date pickers, check boxes, etc.