Introduction
One feature of CurionLib
creates a simple data entry form fairly quickly. On the simple side, its data meets control, out pops a ui. It supports editing a single object as well as collections of objects. It's fairly extensible and was designed to allow a fair amount of design-time and run-time customization.
This article and two others are included in the documentation directory of the library.
There are four sample applications. Demo.plain and Demo.mui use Demo.common and have the same content. Demo.plain has very little styling. Demo.mui uses Modern.UI for styling. Demo.designer shows a several settings that can be used to customize a form. Demo.tiny is a small app that is one step beyond the sample app below. It shows using a collection, navigating, adding, deleting, and custom commands.
Getting Started
The proof, as they say, is in the pudding. So what does it actually take to get a form off the ground?
- Add a reference to CurionLib.dll.
- Add a
ItemForm
control to a Window or User Control:
- Create a class.
- Set
ctlForm.DataContext
to an instance of the class.
Here's the completed Window:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:curion="http://curion.net/Forms"
x:Class="MainWindow"
Title="MainWindow" Height="140" Width="320">
<Grid>
<curion:ItemForm x:Name="ctlForm" />
</Grid>
</Window>
Here's a quick sample class:
Class Person
Public Property Name As String
Public Property Age As Integer
Public Sub Hello()
MsgBox(String.Format("Hello {0}. I see you're {1} years old.", Name, Age))
End Sub
End Class
And the code on your form:
Class MainWindow
Sub New()
InitializeComponent()
ctlForm.DataContext = New Person
End Sub
End Class
If all went well, you should see something like this when you run the app:
Enter your name and age and click the Hello button and you should see a message box confirming your name and age.
Continuing a bit further, Demo.tiny extends the example by using a collection of people, adding navigation, add, delete, and display current record contents. It looks like this:
I know you're probably thinking, these weren't very exciting. The good news is there's a bit more to the control, hang on a bit.
Organization
The code is organized in a few namespaces.
Curion.WPF.Controls
- Most of the controls.
ActionStack
- A custom control class that creates a list of buttons from anonymous methods.CommandStack
- A custom control class that creates a list of buttons for each method in the CommandSource
with no parameters.ContextDefaults
- A class that localizes changes to Defaults
. Designed to be used in a Using
block to temporarily change defaults for example when creating a form.DynamicCommand
- Creates a command for each no parameter method in CommandSource
that can be executed by name.Filter
- A custom control class that is not intended to be used directly. It is an ICollectionView
filter control that consists of a Textbox
(the filter), a TextBlock
(the count of items), and a CommandStack
(optional buttons that do stuff).FilterList
- A custom control class that filters items in a ListBox
based on the text entered.MappedContentButton
- A factory class that creates a button and can optionally use mapped values or functions to create content for the buttons.MemoryDefaults
- A class that implements IDefaults
. A memory based implementation of Defaults
which is used to supply initial values for various classes.mSupport
- A few shared support routines.MyCornerRadiusConverter
- Convert corner radius to and from 1, 2, or 4 values.MyGridLengthConverter
- Convert grid length to and from string. Supports A=Auto, #*=Star lengths, #=Pixels.MyThicknessConverter
- Converts thicknesses to and from 1, 2, or 4 values.NamedBrushConverter
- Converts solid brushes using hex, color names, and windows system color names to and from stringsNamedColorConverter
- Converts colors using hex, color names, and windows system color names to and from stringsSimpleButton
- A factory class that creates a basic button.StringTitleConverter
- Converts csv separated alignment and text to and from a FrameworkElement. ex: Center,My Title or Right,My Title
Curion.WPF.Controls.Form
- Classes used by the form controls.
BooleanCheckBoxColumnFactory
- A factory class that creates a checkbox control.BooleanToggleColumnFactory
- A factory class that creates a toggle button control.BorderColumnFactory
- A factory class that creates a border control.ButtonColumnFactory
- A factory class that creates a button control.ColorColumnFactory
- A factory class that creates a color textbox control.ComboBoxColumnFactory
- A factory class that creates a combo box control.CornerRadiusColumnFactory
- A factory class that creates a corner radius text box control.DateColumnFactory
- A factory class that creates a date picker control.DecimalColumnFactory
- A factory class that creates a decimal text box control.DoubleColumnFactory
- A factory class that creates a double text box control.ExpanderColumnFactory
- A factory class that creates an expander control.GridLengthColumnFactory
- A factory class that creates a gridlength text box control.GroupBoxColumnFactory
- A factory class that creates a group box control.HeadingColumnFactory
- A factory class that creates a heading control.HorizontalAlignmentColumnFactory
- A factory class that creates a horizontal alignment combo box control.ImageColumnFactory
- A factory class that creates an image control.IntegerColumnFactory
- A factory class that creates an integer text box control.IntegerSliderColumnFactory
- A factory class that creates an integer slider control.ItemForm
- A custom control class for a single item form.ItemsForm
- A custom control class for a form with a collection of items.ListBoxColumnFactory
- A factory class that creates a list box control.LongColumnFactory
- A factory class that creates a long control.MakeCsvColumns
- A factory class that creates a list of control factories for each read/write property matching a csv list using mappers.MakeCsvForm
- A factory class that lays out controls for a form using a special line by line csv layout. csv layouts allow placing multiple controls on a single line. May contain a title and places; headings (#
), horizontal rules (-
), blank lines (_
), buttons ({[-|+|*][header=]methodName}
) and columns (columnName[=width]
) using the csv layout.MakeSimpleColumns
- A factory class that creates a list of control factories for each read/write property using mappers.MakeSimpleForm
- A factory class that lays out controls for a form from top to bottom. May contain a Title
if specified and will layout buttons on the form (on top by default). Use in conjunction with MakeCsvColumns to limit the columns displayed or change the prompts.MakeSimpleHeader
- A factory class that makes a label for use as a header on a form .MakeXmlForm
- A factory class that lays out controls using a simple xml layout. xml layouts allow creating boxed regions. The regions (group
) can be oriented vertically or horizontally (columns
) and place controls within the region by using a csv layout (csv
). Regions may be GroupBox
, Expander
, Border
, or Clear
(no decoration) regions. The csv layout is from MakeCsvForm
.ManageArrayItems
- Manages adding, deleting, and retrieving a view for an Array collection.ManageArrayListItems
- Manages adding, deleting, and retrieving a view for an ArrayList collection.ManageClassColumns
- Manages retrieving a list of columns, getting column type, getting and setting column values for an object.ManageCollectionItems
- Manages adding, deleting, and retrieving a view for a Collection collection.ManageCollectionView
- Manages adding, deleting, and retrieving a view for a CollectionView collection.ManageDataListItems
- Manages adding, deleting, and retrieving a view for a Curion DataList collection.ManageDataListRowColumns
- Manages retrieving a list of columns, getting column type, getting and setting column values for a curion data list row.ManageDataRowColumns
- Manages retrieving a list of columns, getting column type, getting and setting column values for a data row.ManageDataTableItems
- Manages adding, deleting, and retrieving a view for a DataTable collection.ManageDataViewItems
- Manages adding, deleting, and retrieving a view for a DataView collection.ManageDictionaryColumns
- Manages retrieving a list of columns, getting column type, getting and setting column values for a dictionary of values.ManageDynamicObjectColumns
- Manages retrieving a list of columns, getting column type, getting and setting column values for a dynamic object.ManageExpandoObjectColumns
- Manages retrieving a list of columns, getting column type, getting and setting column values for an expando object.ManageGenericItems
- Manages adding, deleting, and retrieving a view for a generic collection aka List(Of Type), ObservableCollection(Of Type), etc.MarginConverter
- Convert margin to and from 1, 2, or 4 string values.MemoColumnFactory
- A factory class that creates a memo field control.SelectIManageColumns
- Select column manager.SelectIManageItems
- Select collection / items manager.SingleColumnFactory
- A factory class that creates a single text box control.SolidBrushColumnFactory
- A factory class that creates a solid brush text box control.StringTitleColumnFactory
- A factory class the creates a title textblock control from text and alignmentSuspendFormGeneration
- Class that suspends form generation, designed to be used in a using
block while initially configuring a form.TextBoxColumnFactory
- A factory class that creates a text box.ThicknessColumnFactory
- Convert thickness to and from 1, 2, or 4 string values.
DateRules
, DecimalRules
, DoubleRules
, IntegerRules
, LongRules
, SingleRules
, TextRules
- Classes that implement basic validation rules for data entry controls
Here's a quick reference of the form classes:
Curion.Data
- Some miscellaneous data classes
DataFilter
- A data class that provides column names, values, and parameter names. Used by SQLTable
to filter data.Parameter
- A data class that provides column name and value. Used to pass parameters to SQL Server.
Curion.Data.Sql
- Some SQL Server support classes
SqlTable
- A class that provides a simplified method of creating a DataList
for a SQL Server table and saving changes.SqlSupport
- A module with some SQL Server support routines.
Curion.Data.List
- Classes that support DataList
DataList
- A dynamic object class similar in usage to a DataTable
.Column
- A class that represents a column in a DataList
.Row
- A class that represents a row in a DataList
.ColumnCollection
- A class containing a collection of Column
for a DataList
.RowCollection
- A class containing a collection of Row
for a DataList
.CompareRow
- A class that compares two rows of a DataList
using a list of OrderItem
. Used when sorting a DataList
.OrderItem
- A class that tracks a column name and sort direction. Used when sorting a DataList
.
In addition to the classes, there are a number of interfaces used:
IMakeButton
- An interface for making a button. Used by button creating classes. MappedContentButton
and SimpleButton
implement this.IMakeControl
- An interface for making a control. Used by the IMakeColumns
interface.
IFilterView
- An interface for filtering a view. FilterText
and View
will be set and then the Filter
predicate will be retrieved and used to filter the view. Used by ItemForm
. FilterViewFields
implements this.IDefaults
- An interface defines how Defaults are accessed. ContextDefaults
and MemoryDefaults
implement this.IMakeColumns
- An interface for creating column factories. MakeSimpleColumns
and MakeCsvColumns
are implementations of this.IMakeForm
- An interface for creating form factories. MakeSimpleForm
and MakeCsvForm
as implementations of this.IMakeHeader
- An interface for creating header factories. MakeSimpleHeader
is an implementation of this.IGetData
- An interface for retrieving data. SqlTable
is an implementation of this.IHandleChanges
- An interface for handling changed data. SqlTable
is an implementation of this.
Terms
Here's what I mean by a few of the terms I've used:
Defaults
- Defaults
are a collection of values used to drive the initial properties of new classes. Defaults
can be changed globally or in a limited scope.Factory
- Factories are classes or methods that create classes, methods, or values.Mapper
- Mapper
s select items to be used in a particular context. For example in the MakeSimpleColumns
class, the ColumnMapper
maps data types to column factories and the ColumnMapperException
maps specific column names to column factories. In this application, most mappers map a key, such as a datatype or column name, to a function. Using anonymous methods, this allows a high degree of customization of the factory instantiation.Header
- The prompt that is normally displayed before a field.Column
- A factory that creates a .NET control.
What Does It Work With
ItemForm
was designed to work with a single object. To use a single object, set the DataContext
property. It has been designed to work with a POCO (plain old CLR object, i.e. your class), ExpandoObject
, DataRow
, DataList Row
, DynamicObject
, or Dictionary
.
ItemsForm
was designed to work with collections of objects supported by ItemForm
. To use a collection, set the ItemsSource
property. The View
property will be available that will return the current ICollectionView
in use.
For POCO collections, each item can be of a different type and a new UI will be created for each. While this can be pretty cool in certain circumstances, one of the downsides is that RepeatButtons
don't really work well, since they're re-generated for each new class / form.
Using the Control
There are two demo applications that show the controls in use. DemoApp
is a generally unstyled WPF application to give you a feel for what it looks like out of the box. Wherever possible, I've used control wrapping to extend controls as opposed to inheriting controls. The result of this is that it should be fairly easy to use your Theme with the control. DemoAppMUI
is an example of using a theme, MUI or Modern.UI in this case.
Both applications use Customer.xml in a few places. It's a small XML file with 1,000 randomly generated customers and a few data types.
DemoApp
Shows using single objects, lists of objects with a custom pager, and lists of objects using a ListBox
pager. Madness demonstrates using a list containing multiple types with one or more methods. And finally Separate command object demonstrates some basic overall form customization and using mapped content buttons.
All of the forms except Madness use the customer.xml records and can be displayed as a simple form, csv layout, or xml layout form by selecting the corresponding option button in the upper left corner of the app.
DemoAppMUI
Demonstrates the use of single and multi-item lists with theming which is provided by mui. The pages that are displayed are in the Pages folder and organized roughly the same as the menu. Of particular note:
- Custom/CSV form which shows many of the features including headers, listboxes, options, and mapping to enums.
- Custom/List Nav and List Nav2 which show customizing separators.
- Custom/MiscControls which shows a filtered list box.
- And utility which is another example similar to the first one that generates basic dependency properties. It also demonstrates creating a default button.
MakeCsvForm
One of the controls with a good deal of customization is the MakeCsvForm
control's layout. Here's a quick overview of the meaning of the lines. Note that text in [] are optional except as noted for the CommandButton
.
#Heading | Displays a header. Must be the first entry on a line and is considered to be the only entry on the line. |
- (dash) | Draws a horizontal rule. Must be the first entry on a line and is considered to be the only entry on the line. |
_ (underline) | Puts in a blank line. Must be the first entry on a line and is considered to be the only entry on the line. |
{button1[,button2...]} | Places one or more CommandButton s (buttons for methods with no parameters) on a single line. In the current implementation, buttons will grow up to 640 pixels wide and then wrap. A button can have the following prefixes:
- * - Create a repeat button. Cannot be used with + or - prefixes.
- + - Create a default button.
- - - Create a cancel button.
In addition, buttons take the form of either header=columnName or columnName . If they take the second form, a simple conversion from Camel casing is done. If a button name is omitted, spacing is inserted (i.e., First,,Last). Multiple commas can be used to create increased spacing. Must be the first entry on a line and is considered to be the only entry on the line.
|
column1[=width][,column2...] | Places one or more columns on a line of the form. column1 is assumed to be the name of a column in the current object. width can take the following forms:
- # - A fixed width in pixels, i.e., zipcode=80
- #* - A proportional width in pixels. ex: address=1*
- A - Auto-sized to contents.
If omitted, a width of 1* is assumed.
|
DemoApp
uses the following layout:
Name,Phone=100
-
Address
City,State=50,Zipcode=80
-
Balance=100,Added=100,IsActive=23
{First,*Prior,*Next,Last,,Show}
Update 1.0.0.1
Added IntegerSlider
, BooleanToggle
, BorderColumn
, ExpanderColumn
, GroupBoxColumn
, MakeXmlForm
. Two breaking changes header character was changed from > to # for csv layouts, and button maker is now a factory function. Other misc changes, see 0Changes.txt for more info.
MakeXmlForm Added MakeXmlForm
- <cols [height="value"]> - Arrange child nodes as columns.
- <box [width="value"] [title="value"] [type="expander|groupbox|border|clear"] [isopen="true|false"]> - Group child nodes in a box container specified by type.
- <csv [width="width"]> - generate a csv layout. InnerText is the csv layout.
Nodes not directly under a <columns> tag are assumed to be on subsequent rows.
Xml layout from sample applications
<layout>
<cols>
<box title="Person" isopen="true" type="expander">
<csv>
Name,Phone=100
</csv>
</box>
<box title="Misc" width="214" isopen="true" type="expander">
<csv>
Balance=100
Added=100
IsActive=23
</csv>
</box>
</cols>
<box title="Address" type="expander">
<csv>
#Address
Address
City,State=50,Zipcode=80
</csv>
</box>
<csv>
_
{First,*Prior,*Next,Last,,Show}
</csv>
</layout>
Update 2.0.0.0
Changed version to 2.0 because of the number of breaking changes, title change, and splitting the form into two controls. Here's some of the changes, see 0Changes.txt for the rest.
Breaking Changes
- Renamed
IMakeColumn
to IMakeColumns
to clarify intended use. - Moved
ButtonMaker
to ItemForm
. - In
MakeXmlForm
, renamed linegroup
to columns
, container
to box
, and lines
to csv
. - Split and renamed
DataForm
. ItemForm
has a DataContext
takes a single item. ItemsForm
has an ItemsSource
with related routines. Should be more clear when using controls. IMakeColumns.Create
initial parameter changed from obj As Object
to base As ItemForm
. This was done to facilitate re-using ItemForms
ability to return a list of column names and retrieve the values for those columns. This should ultimately also provide greater flexibility in writing column generators.- Updated the
Create
method of IMakeHeader
interface to include an ItemForm
and column name. Should allow for more customization of headers. - Changed command button delimeters from [] to {}. Should make documentation easier to read...
Other changes of note:
- Added
ColumnNames
to ItemForm
, returns column names for current DataContext
object. - Added default property
Item(columnName As String) As Object
to ItemForm
. Can get/set property values of current DataContext
. - Added
IMakeControl
and updated column generators (MakeCsvColumns
, MakeSimpleColumns
) to select IMakeControl
interfaces instead of BaseColumnFactory
. - Added navigation and Add, Delete to ItemsForm.
- Added some converters and factories for new column types.
- Added IManageItems and ISelectManageItems to handle collection navigation, adding, deleting, and retrieving a view.
- Added IManageColumns and ISelectMangeColumns to handle retrieving column names, types, and getting, setting column values.