Monday, April 26, 2010

Auto Complete Box Control in WPF

If you have work in silverlight 3.0 then you have see the auto complete box control is there to help the user to search from the possible list of value when user type in text box. When I have used that control I though of similar control in the WPF , I have search on net by using Google and found some simple auto complete text box control on net.But I have decided to create one for myself and then share it with people on my blog. So here is my first ever control which I want to share it with you. Below are the two image of the control. In the first image you can see simple text box control and a button control but in the second image you see the drop down with possible list of matched values.




Let us start with properties of the control , Below are the list of properties which are offered by the control. I have given some description for each of the property. First I have listed the dataSource property which is used to set the data source for the control. Then is the displayColumn Name which is used to display value of the column when you click on the dropDown list. DataSource and DisplayColumnName Properties are primary properties which user has to set otherwise control will not work.
Property
Description
DataSourceData source to display dropdown list.
DisplayColumnNameName of the column which is used to display in the text box when user select from the dropdown list.
DropdownHeightUsed to set the height of the Dropdown list
ReturnValueReturn value is a DataRow, whole row of the dataSource table.
MinimumSearchLengthMinimum search length is used to search in the list, e.g if set to 2 then search is perform and dropdown list will be open when the text box contain atleast 2 characters.

Then is the DropDownHeight which is used to set the height of the dropDownList. The ReturnValue is the dataRow , when user select from the dropDownlist then it will return whole row of the DataSource , so if you can get the whole selected record and you can get whatever you want from that row, mean primary key, display Column name etc.
The interesting part of the control is when you use the BindingColumn class to pass the parameter to the bindingColumn function of the autoCompleteBox class. The Class consist of four properties HeaderText, BindingColumnName, FilterOption and IsSearchable. HeaderText is used to display Text as header in grid and BindingColumnName is used to bind the column from the dataSource to the grid to display the value. The filder option Consist of 3 option StartWith, Contains and EndWith option, what ever you pass that column is search accordingly in the list and the IsSearable is used to sepecify whether the current column is search-able or not.
Hope you will like that control. if you have any suggestion then please share it with me, I have included the autoCompleteBox dll in that project. You can use it and if you need source code I will share it with you. You can download the source code from here
All and any comments / bugs / suggestions are welcomed!

Saturday, April 10, 2010

RowDetailTemplate of DataGrid control

When I started my learning of silver light 3.0, and see the control offered by the tool, one of the controls which I like most in every programming language is the data grid control. The feature offered by the new data grid control are very good especially the RowDetail. Which is the best feature from my point of view as you can show additional detail of the record in the Row Detail, it is mostly used when you have situation where you need to show parent and child records. When I used data grid control in silver light application the question in my mind was how to display data grid in the RowDetail, and I have search on it on Google but didn’t find good solution at that time. But now once again I have tried again and now this time I have find the solution of displaying data grid in the RowDetail. Below is the main data grid when user didn't click on any of the row.
And here is the row detail of the grid when user click on any of the data grid row, to see the more detail about the record.

Let us start with our example code I have one data grid control and in that data grid control I have placed another data grid control which is placed in the RowDetail template. I have two classes one for with the name of Persons and second one with the name of PersonDetail. In the Person class I have following properties user id, first name, last name, email address and the contact number. In PersonDetail class I have Parent ID, Programming language and the skills level properties. I have just used the programming languages such as WPF, WCF , silver light, php , asp.net etc. for just display purpose and each record in the Persons class has two child records so that when user click on any of the row , it shows its relevant record, I have also displayed the Parent ID in the child table so that you can see the relation ship id as well. Below is my xaml code, here you can see that I have placed grid control in the RowDetailTemplate of the main data grid, and I have also set the columns properties such as header , binding etc of the child data grid control.
<data:DataGrid Margin="5,5,5,0" x:Name="dgrdDataGrid" GridLinesVisibility="Horizontal" AutoGenerateColumns="False" VerticalAlignment="Top" RowDetailsVisibilityChanged="dgrdDataGrid_RowDetailsVisibilityChanged" IsReadOnly="True">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="User ID" Width="80" Binding="{Binding UserID}" CanUserReorder="False"/>
<data:DataGridTextColumn Header="First Name" Width="150" Binding="{Binding FirstName}" CanUserReorder="False" />
<data:DataGridTextColumn Header="Last Name" Width="150" Binding="{Binding LastName}" CanUserReorder="False"/>
<data:DataGridTextColumn Header="Email Address" Width="150" Binding="{Binding EmailID}" CanUserReorder="False"/>
<data:DataGridTextColumn Header="Contact" Width="100" Binding="{Binding ContactNumber}" CanUserReorder="False"/>
</data:DataGrid.Columns>
<data:DataGrid.RowDetailsTemplate>
<DataTemplate>
<data:DataGrid x:Name="dgrdRowDetail" Width="400" AutoGenerateColumns="False" HorizontalAlignment="Center" IsReadOnly="True">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="Parent ID" Binding="{Binding ParentID}"/>
<data:DataGridTextColumn Header="Programming Language" Binding="{Binding ProgrammingLanguages}"/>
<data:DataGridTextColumn Header="Skill Level" Binding="{Binding SkillLevel}"/>
</data:DataGrid.Columns>
</data:DataGrid>
</DataTemplate>
</data:DataGrid.RowDetailsTemplate>
</data:DataGrid>
Next the important thing is I have registered the RowDetailsVisibilityChanged event of the main data grid control , which is fired when RowDetailVisibilityMode property value changes, when user click on any of the row then it will fires , and in this event I will filter the records depending on the Persons ID and then assign it to the RowDetail data grid control.
Here is the complete code of the RowDetailVisibilityChanged event handler, here you can see that I have place if condition to check the dataContext of the row for null and then use form filter of the data to get only record which are matched with the current user id.

try
{
if (e.Row.DataContext != null)
{
var objCurrentRecordDetail = from tblPersonDetail in objPersonDetail
where tblPersonDetail.ParentID == ((Persons)e.Row.DataContext).UserID
select tblPersonDetail;

((DataGrid)e.DetailsElement).ItemsSource = objCurrentRecordDetail;
}
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message, "Error", MessageBoxButton.OK);
}
Next is the statement which is used to assigned the item source of the data grid which is placed in the RowDetail. Here I have used the EventArgs parameter of the RowDetailVisibilityChanged event handler and use the property DetailElement, as I have only one control in the RowDetail , so here I can find the main data grid control in the DetailElement property. Suppose if you have Grid layout in the RowDetail and you have your own display of the RowDetail then you can use e.DetailsElement.FindName("dgrdRowDetail") to find the data grid in my case and any of the control which you want to search in the grid control. In this case e.DetailElement Property will return you the grid control. Then you have to search for your control in that grid layout.You can download the source code from here
All and any comments / bugs / suggestions are welcomed!

Sunday, April 4, 2010

Google Map For Beginners

I was just working understand how the Google maps work and how developer use the Google maps in there web site. Now I have created a sample page for the Google map and I would like to share this example with you so that you can also get starting point of the Google maps.Below is the image of the example. Here you can see that I have Google map and one table below the Google map( will describe later).

Image 1
And here is the what I want to achieve , I want to get all possible result when user click on particular on the Google maps and that result should be displayed in table like format.

Image 2

In order to get started with Google what you have to do is to get a Google map key, the Google map key is important if you want to place you project live, if you used it locally on your PC then you don't need any Google Key.To get Google map key you can go here to get the Google map key. From there what you have to do is to give the URL of your web site. For example my blog URL is http://asimsajjad.blogspot.com, So I have to put this URL in "My web site URL" input box and accept the terms and click the Generate Key button. In the next page you have four ways to include Google map key in your project, first one is simple key, second one is the Script tag that include key, maps API for flash and HTTP Service example. for you if you need to used it in the web project you go for second option "JavaScript Maps API Example".

< script src="http://maps.google.com/maps?file=api&v=2&sensor=false&key=ABQIAAAA8RrNA2ad3sXGIzKjA4Rq5hSMhSD8o7XRZ8sp4sebDRHHwO96tRQCUNJChXwnEcob6qAGQYpm4rNG6Q"
type="text/javascript"> < /script>

Use of the Google Maps API now requires that you indicate whether your application is using a sensor (such as a GPS locator) to determine the user's location. This is especially important for mobile devices. Applications must pass a required sensor parameter to the <script > tag when including the Maps API javascript code, indicating whether or not your application is using a sensor device.Applications that determine the user's location via a sensor must pass&sensor=true when loading the Maps API JavaScript via either the http://maps.google.com/maps or with the Common Loader.

Note: As in my case I have give base URL of my blog, Now I can use this key for multiple pages on my blog if you want to generate key per page then you have to give complete URL including page name in the "My web site URL", But it is best to have same key for all the pages in the web site.

Next you have to put below tag in the body of the form and note that the id of the div tag. As this id is used to load the Google map, and will be passed to the GMap2 constructor.
< div id="map_canvas" style="width: 800px; height: 600px; border: 0px solid #466094;background-color: #EEF0F6;">
< /div>
Below is the my code which is used to initialize the object and load the Google map , and the initialize function is called when the window is loaded.The JavaScript class that represents a map is the GMap2 class. Objects of this class define a single map on a page. When you create a new map instance, you specify a DOM node in the page (usually a div element) as a container for the map. HTML nodes are children of the JavaScript document object, and we obtain a reference to this element via the document.getElementById() method.

var googleMap;
var geocoder;
var address; ;

function initialize() {
if (GBrowserIsCompatible()) {
googleMap = new GMap2(document.getElementById("map_canvas"));
googleMap.setCenter(new GLatLng(53.3042827, -6.2401578), 13);
point = new GLatLng(53.3042827, -6.2401578);
marker = new GMarker(point);
googleMap.addOverlay(marker);
googleMap.setUIToDefault();
geocoder = new GClientGeocoder();
GEvent.addListener(googleMap, "click", function(overlay, latlng) {
address = latlng;
geocoder.getLocations(latlng, showAddress);
});
}
}
Once you have created a map via the GMap2 constructor, we need to initialize it. This initialization is accomplished with use of the map's setCenter() method. The setCenter() method requires a GLatLng coordinate and a zoom level and this method must be sent before any other operations are performed on the map, including setting any other attributes of the map itself. Additionally, we also call setUIToDefault() on the map. This method sets up the map's user interface (input handling and set of controls) to a default configuration, including pan and zoom controls, selection of map types, etc. See Using the Default Maps UI in the Controls chapter for more information.
I have also declare the variable of geocoder name which is used for the reverse coding.The term geocoding generally refers to translating a human-readable address into a point on the map. The process of doing the converse, translating a point into a human-readable address, is known as reverse geocoding. I have also attached click event with the googleMap object. In the click event of the googleMap object I have used the function of getLocations of geocoder object .The GClientGeocoder.getLocations() method supports both standard and reverse geocoding. If you pass this method a GLatLng object instead of a String address, the geocoder will perform a reverse lookup and return a structured JSON object of the closest addressable location. Note that the closest addressable location may be some distance from the original latitude and longitude values of the query, if the supplied GLatLng is not an exact match for any addressable locations.For the accuracy you can see the following below is the table with the constant value and description.
Constant
Description
0Unknown location
1
Country level accuracy.
2
Region (state, province, prefecture, etc.) level accuracy.
3
Sub-region (county, municipality, etc.) level accuracy.
4
Town (city, village) level accuracy.
5
Post code (zip code) level accuracy.
6
Street level accuracy.
7
Intersection level accuracy.
8
Address level accuracy.
9
Premise (building name, property name, shopping center, etc.) level accuracy.

Hope you can get some starting point of how to use Google map in your applications.Click Here To view online sample.

References:
1- Map Basics
2- Google Maps API Concepts
3- Services

All and any comments / bugs / suggestions are welcomed!