Google Search

Google
 

Monday, April 14, 2008

Creating and Using Silverlight and WPF User Controls

One of the fundamental design goals of Silverlight and WPF is to enable developers to be able to easily encapsulate UI functionality into re-usable controls.

You can implement new custom controls by deriving a class from one of the existing Control classes (either a Control base class or from a control like TextBox, Button, etc). Alternatively you can create re-usable User Controls - which make it easy to use a XAML markup file to compose a control's UI (and which makes them super easy to build).

In Part 6 of my Digg.com tutorial blog series I showed how to create a new user control using VS 2008's "Add New Item" project item dialog and by then defining UI within it. This approach works great when you know up front that you want to encapsulate UI in a user control. You can also use the same technique with Expression Blend.

Taking Existing UI and Encapsulating it as a User Control

Sometimes you don't always know you want to encapsulate some UI functionality as a re-usable user control until after you've already started defining it on a parent page or control.

For example, we might be working on a form where we want to enable a user to enter shipping and billing information. We might begin by creating some UI to encapsulate the address information. To-do this we could add a control to the page, nest a grid layout panel inside it (with 2 columns and 4 rows), and then place labels and textbox controls within it:

After carefully laying it all out, we might realize "hey - we are going to use the exact same UI for the billing address as well, maybe we should create a re-usable address user control so that we can avoid repeating ourselves".

We could use the "add new item" project template approach to create a blank new user control and then copy/paste the above UI contents into it.

An even faster trick that we can use within Blend, though, is to just select the controls we want to encapsulate as a user control in the designer, and then "right click" and choose the "Make Control" menu option:

When we select the "Make Control" menu item, Blend will prompt us for the name of a new user control to create:

We'll name it "AddressUserControl" and hit ok. This will cause Blend to create a new user control that contains the content we selected:

When we do a re-build of the project and go back to the original page, we'll see the same UI as before - except that the address UI is now encapsulated inside the AddressUserControl:

We could name this first AddressUserControl "ShippingAddress" and then add a second instance of the user control to the page to record the billing address (we'll name this second control instance "BillingAddress"):

And now if we want to change the look of our addresses, we can do it in a single place and have it apply for both the shipping and billing information.

Data Binding Address Objects to our AddressUserControl

Now that we have some user controls that encapsulate our Address UI, let's create an Address data model class that we can use to bind them against. We'll define the class like below (taking advantage of the new automatic properties language feature):

Within the code-behind file of our Page.xaml file we can then instantiate two instances of our Address object - one for the shipping address and one for the billing address (for the purposes of this sample we'll populate them with dummy data). We'll then programmatically bind the Address objects to our AddressUserControls on the page. We'll do that by setting the "DataContext" property on each user control to the appropriate shipping or billing address data model instance:

Our last step will be to declaratively add {Binding} statements within our AddressUserControl.xaml file that will setup two-way databinding relationships between the "Text" properties of the TextBox controls within the user control and the properties on the Address data model object that we attached to the user control:

When we press F5 to run the application we'll now get automatic data-binding of the Address data model objects with our AddressUserControls:

Because we setup the {Binding} declarations to be "Mode=TwoWay", changes users make in the textboxes will automatically get pushed back to the Address data model objects (no code required for this to happen).

For example, we could change our original shipping address in the browser to instead go to Disneyland:

If we wire-up a debugger breakpoint on the "Click" event handler of the "Save" button (and then click the button), we can see how the above TextBox changes are automatically reflected in our "_shippingAddress" data model object:

We could then implement the SaveBtn_Click event handler to persist the Shipping and Billing Address data model objects however we want - without ever having to manually retrieve or manipulate anything in the UI controls on the page.

This clean view/model separation that WPF and Silverlight supports makes it easy to later change the UI of the address user controls without having to update any of our code in the page. It also makes it possible to more easily unit test the functionality (read my last post to learn more about Silverlight Unit Testing).

Summary

WPF and Silverlight make it easy to encapsulate UI functionality within controls, and the user control mechanism they support provides a really easy way to take advantage of this. Combining user controls with binding enables some nice view/model separation scenarios that allow you to write very clean code when working with data.

You can download a completed version of the above sample here if you want to run it on your own machine.

Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)


LINQ (language integrated query) is one of the new features provided with VS 2008 and .NET 3.5. LINQ makes the concept of querying data a first class programming concept in .NET, and enables you to efficiently express queries in your programming language of choice.

One of the benefits of LINQ is that it enables you to write type-safe queries in VB and C#. This means you get compile-time checking of your LINQ queries, and full intellisense and refactoring support over your code:

While writing type-safe queries is great for most scenarios, there are cases where you want the flexibility to dynamically construct queries on the fly. For example: you might want to provide business intelligence UI within your application that allows an end-user business analyst to use drop-downs to build and express their own custom queries/views on top of data.

Traditionally these types of dynamic query scenarios are often handled by concatenating strings together to construct dynamic SQL queries. Recently a few people have sent me mail asking how to handle these types of scenarios using LINQ. The below post describes how you can use a Dynamic Query Library provided by the LINQ team to dynamically construct LINQ queries.

Downloading the LINQ Dynamic Query Library

Included on the VS 2008 Samples download page are pointers to VB and C# sample packages that include a cool dynamic query LINQ helper library. Direct pointers to the dynamic query library (and documentation about it) can be found below:

Both the VB and C# DynamicQuery samples include a source implementation of a helper library that allows you to express LINQ queries using extension methods that take string arguments instead of type-safe language operators. You can copy/paste either the C# or VB implementations of the DynamicQuery library into your own projects and then use it where appropriate to more dynamically construct LINQ queries based on end-user input.

Simple Dynamic Query Library Example

You can use the DynamicQuery library against any LINQ data provider (including LINQ to SQL, LINQ to Objects, LINQ to XML, LINQ to Entities, LINQ to SharePoint, LINQ to TerraServer, etc). Instead of using language operators or type-safe lambda extension methods to construct your LINQ queries, the dynamic query library provides you with string based extension methods that you can pass any string expression into.

For example, below is a standard type-safe LINQ to SQL VB query that retrieves data from a Northwind database and displays it in a ASP.NET GridView control:

Using the LINQ DynamicQuery library I could re-write the above query expression instead like so:

Notice how the conditional-where clause and sort-orderby clause now take string expressions instead of code expressions. Because they are late-bound strings I can dynamically construct them. For example: I could provide UI to an end-user business analyst using my application that enables them to construct queries on their own (including arbitrary conditional clauses).

Dynamic Query Library Documentation

Included with the above VB and C# Dynamic Query samples is some HTML documentation that describes how to use the Dynamic Query Library extension methods in more detail. It is definitely worth looking at if you want to use the helper library in more depth:

Download and Run a Dynamic Query Library Sample

You can download and run basic VB and C# samples I've put together that demonstrate using the Dynamic LINQ library in an ASP.NET web-site that queries the Northwind sample database using LINQ to SQL:

You can use either Visual Web Developer 2008 Express (which is free) or VS 2008 to open and run them.

Other Approaches to Constructing Dynamic LINQ Queries

Using the dynamic query library is pretty simple and easy to use, and is particularly useful in scenarios where queries are completely dynamic and you want to provide end user UI to help build them.

In a future blog post I'll delve further into building dynamic LINQ queries, and discuss other approaches you can use to structure your code using type-safe predicate methods (Joseph and Ben Albahari, authors of the excellent C# 3.0 In a Nutshell book, have a good post on this already here).

Friday, April 4, 2008

Table Partitioning in Sql server

Table partitioning is the concept introduced in sql server 2005. Its used to enhance faster database accessibility.
It may be either Horizontal partitioning or Vertical partitioning.
Horizontal Partitioning:In this type, the rows will be segregated as two tables (Old table and new table). Its a logical seperation placed in different file groups.If i want to access most recent data frequently when compared to old data then horizontal partitioning paves the way for this. It's highly advisable to implement this concept in multi processor environment.Schema remains the same in horizontal partitioning.
Vertical partitioning:Its nothing but segregating the columns of the table, part of the column in one table and other part of the column in other table(in case of partitioning into two tables).

Table valued parameters

It's a new T-SQL enhancements done in sql server 2008 which allows us to pass the table as parameters for our stored procedure. In the client server architecture we used to pass individual rows from the front end and its get updated in the backend. Instead of passing individual rows, Microsoft released a new enhancement referred to as table value parameters where they are providing a flexibility to pass the table as a parameter from the front end.


Features:
1. Processing speed will be comparitively very faster.
2. We have to declare the table as a Readonly one. DML operations cannot be done on the table.
3. From the front end we have to pass the data in the form of structures.
4. Reduces roundtrip to the server
5. Processes complex logics at a stretch in one single routine.


-- Am trying to create a table "EmployeeTable" with three fields.
CREATE TABLE EmployeeTable
(id int,
[name] varchar(100),
designation varchar(100))

-- Creating a stored procedure "TableValuedSampleProc" to insert the rows.
CREATE PROCEDURE TableValuedSampleProc (@id int, @name varchar(100),@designation varchar(100))
AS
BEGIN
insert into EmployeeTable values (@id,@name,@designation)
END
-- Executing the stored procedure
EXEC TableValuedSampleProc 1,'one','manager'
EXEC TableValuedSampleProc 2,'two','sr tlr'
EXEC TableValuedSampleProc 3,'three','tlr'
SELECT * FROM EmployeeTable
-- Am trying to create a table type "EmployeeTableType"
CREATE TYPE EmployeeTableType AS TABLE
(ID int, [name] varchar(100),designation varchar(100))
-- Creating the stored procedure in insert the data using Table type.
CREATE PROCEDURE EmployeeTableTypeProc (@EmployeeTempTable EmployeeTableType READONLY)
AS
BEGIN
INSERT INTO EmployeeTable
SELECT * FROM @EmployeeTempTable
END
-- Building a temporary table type
DECLARE @TempEmployee EmployeeTableType
INSERT INTO @TempEmployee VALUES (1,'one','manager')
INSERT INTO @TempEmployee VALUES (2,'two','sr tlr')
INSERT INTO @TempEmployee VALUES (3,'three','tlr')
-- Executing the stored procedure by passing the temporary table type
EXEC EmployeeTableTypeProc @TempEmployee
-- Checking the existence of data
SELECT * FROM EmployeeTable

pivot table

One of the most requested pieces of code on the Internet forums about SQL Server these days, is the code for making a crosstab query. There was no native support for that in version 6.5. Not even version 7.0 or version 2000 had this support.
So when Microsoft announced that SQL 2005 would support crosstab queries we all (well, at least me) cheered and anticipated that this should solve a number of difficulties. Many of us have worked with MS Access since version 2.0, and in this application, pivot tables are breazes.



declare @SQLTable1 table (id int,Studentname varchar(100))
declare @SQLTable2 table (id int,Marks int)
-- inserting the data into the table variables
insert into @SQLTable1
select '1','one' union all
select '2','two' union all
select '3','three' union all
select '4','four'
insert into @SQLTable2
select '1','90' union all
select '1','20' union all
select '1','80' union all
select '2','78' union all
select '2','67' union all
select '3','89' union all
select '3','65' union all
select '3','98' union all
select '4','78' union all
select '4','76' union all
select '4','45'
select * from @SQLTable1
select * from @SQLTable2
--Creating rownumber in the cte
;with lakshmi as(
select a.id,a.Studentname, b.Marks,
row_number() over ( partition by a.id order by a.id) as rn
from @SQLTable1 a inner join @SQLTable2 b on a.id=b.id
)
--select * from VenkatCTE
-- pivoting the rows in the cte
select id,Studentname,[1] as Subject1,[2] as Subject2,[3] as Subject3
from lakshmi
pivot
(
min(Marks) for rn in ([1],[2],[3])
)
pvt
order by id