Dec 6, 2008

Dynamic WPF Page (UI) generation using C#

I have gone through many blogs and support sites and read some of the articles, many of them gave the idea about generating the Dynamic WPF page using VB.Net. But as a developer I always prefer writing the code in C#.

Generating the Page in WPF is very simple. Before going to do this we should have some basic idea about object sources and XML.

WPF supports vector based UI design and it is fully XAML (Extensible Application Markup Language) style, because of this, the code behind totally separated from its UI design.
In this article, I am going to explain about creating dynamic WPF page at runtime. This was really easy using XML literals and XML namespace imports. We can load and save XAML at runtime using the System.Windows.Markup.XamlReader and System.Windows.Markup.XamlWriter classes .

Basically I generate required markup elements at runtime and store it in a StringBuilder, parse the string builder to an XElement and submit that to a ContentControl as its content through XamlReader class.

I am using LINQ to SQL Classes item to get the required table and columns information through a stored procedure.

Step 1#: create a stored procedure in SQL to get required table and column information; this is very simple if we have some idea about using the information_schema schema
CREATE PROCEDURE dbo.spGetTableSchema
@table varchar(50)
c.table_name As TableName,
c.column_name As ColumnName,
c.data_type As DataType,
c.character_maximum_length As MaxLength,
CASE cu.column_name
WHEN null THEN 0
FROM information_schema.constraint_column_usage cu
INNER join information_schema.table_constraints ct
ON ct.constraint_name = cu.constraint_name
ct.constraint_type = 'PRIMARY KEY'
AND ct.table_name = c.table_name
AND cu.column_name = c.column_name
),0) AS IsPrimaryKey
FROM information_schema.columns c
INNER JOIN information_schema.tables t
ON c.table_name = t.table_name
WHERE @table = t.table_name and
(t.table_type = 'BASE TABLE' and not
(t.table_name = 'dtproperties') and not
(t.table_name = 'sysdiagrams'))
ORDER BY c.table_name, c.ordinal_position

Step #2: Open Visual Studio 2008 IDE and create a new WPF browser application and name it as DynamiWPFPage

Explore project view and it looks as follows, open the Page1.xaml in design mode and view the XML code

Step #3: Update the xaml (Page1.XAML) as specified below

Step #4: now we need to add the LINQ to SQL classes item to project. For this, right click on the project and select “Add new item”, from the list select LINQ to SQL classes. Name it as DynamicDataClasses.dbml

The LINQ to SQL Classes item designer will be opened automatically for DynamicDataClasses.dbml

Step #5: Click on View menu in VS2008 IDE and select Server Explorer, this shows the SQL connections list. In the Server Explorer, right click on Data Connections and click on Add new Connection. Then we need to provide the SQL server information to get connected to our SQL Server Northwind database (provide details as shown in the below screen shot).

Explore the newly created connection, select the spGetTableSchema stored procedure from SQL Server, drag and drop the procedure on LINQ to SQL Classes designer, it will be added to methods pane of the designer. Drag and drop the table “Customer” in the LINQ designer

Step #6: Add a new class with required properties (TableSchema) to designer as specified below. Change MaxLength property properties of TableSchema class as specified below

Nullable: make it True
Type : int(system.Int32)

Similarly IsPrimaryKey property Type property also change to int (system.Int32)

Right click on the spGetTableSchema procedure in Methods pane of LINW to SQL designer and selecte properties. Change the ReturnType to TableSchema

Step #7: Now open the Page1.xaml.cs file and add the below code to it. This example creates a Dynamic WPF for Customers table in Northwind database

I could not upload the code due to some technical problem, due to this i posted the code as image here. you can try with it, still you need any support, feel free to contact me

Hope this helps you


No comments: