Monday, December 5, 2011

Add/Remove OptionSet Value at Run time Microsoft Crm 2011

Problem:
           In my post "Loop through OptionSet Using Javascript in Microsoft CRM 2011" regarding how to read all the values in the optionSet of the Microsoft Crm 2011 one of the read post question "Would you know how to remove an option from the list getOptions(), because I want the picklist to show only what needed". So in this post I will give you idea how to add remove optionSet using JavaScript.

Solution:
            For the test code I have used the account entity and from account entity I have choose "Preferred Day" and  "Preferred Time" attributes because these attribute are already added when you create only organization which for trial for 30 day. You can see the selected attributes in the Image 1.

Image 1
JavaScript code is listed in the List 1 here you can see first I have get the selected text of the Preferred Day attribute by using getText and store it in the variable which will then used in the comparison. Then in the next line  I have get the Preferred Time option set control and store it in the variable and then by using that variable get all the optionSet of the Proffered Time optionSet and store it in another variable with name "optionSets". Next I have called clearOptions function to remove all the options from the Preferred time Option set.
List 1

Next is the simple check of the Preferred Day text which user selected. I have set First option which is the Morning for the Monday , Afternoon for the Tuesday and Evening for the Wednesday , All option for the Thursday and first two option for the Friday. Here are some of the screen shots when user click the Monday there are only two option one is the empty and second is the Morning as you can see in the Image 2.
Image 2
And in Image 3 you can see the all option when user select Thursday from the Preferred Day option set.
Image 3
In above JavaScript code I have just use the addOption to add option in the option set which take the option set and the location where to add the option set in the OptionSet dropdown.
 
All and any comments / bugs / suggestions are welcomed!

Sunday, December 4, 2011

Bringing SelectedItem Into Focus Using DataGrid Control

Problem :
              When using datagrid control of the silverlight control there is situation when datagrid control has lots of records and vertical scrolling of the datagrid control is visible and the selected item of the datagrid control is not in the view as the scrolling (vertical scrolling of the datagrid is visible due to large record). So it is important to give focus to the selected item of the datagrid control.In this post I will give you solution of this problem which many of you may have face.
Solution :
               To start with how to solve above problem I have one button control with is used to bring the selected item of the datagrid control in the focus and one datagrid control which is used to show the records. The main form of the test application is shown in the Image 1 here you can see that datagrid display all the records which are assign to it ( as I have small number of records in my grid so i have reduce the height of the datagrid control so that it has vertical scrolling and the selected item is not seen when datagrid control first display). In the Image 1 you can see that selected item is not displayed which I have mention in my problem.

Image 1
The solution to above problem is quite simple but it take time when I first come across this problem. You can see the code used to bring the selected item of the datagrid control in the focus just one line of code which is used. Here I have used ScrollIntoView function of the datagrid control which take The data item (row) to scroll to as its first parameter ( here you can see that I have passed the selected item of the datagrid control) and the second parameter of the ScrollIntoView is the column of the datagrid control(the column to scroll to here I have passed the first column of the datagrid control).

List 1

The output can be seen in the Image 2, when you client the "Selected Item" button then it will focus the selected item of the datagrid control.

Image 2
Note: In the HomeViewModel which is the viewModel for the home page. I have assigned value to the Selectedcustomer before sorting the PagedCollectionView(CustomerList property) so that after sorting the selected item will disappear from the view and it should.If I assigned the first element of the PagedCollectionView (CustomerList) after sorting then first element will be selected..

If you have similar situation then you solved it by using above technique as I have done when I got similar situation.You can download the source code from here.

All and any comments / bugs / suggestions are welcomed!

Communication Between Silverlight And JavaScript (Part 2)

This post is the second part of the series of Communication Between Silverlight And JavaScript. In the First part I have discuss how to call JavaScript from the managed code.Now in this post I will discuss how to call the managed code from the JavaScript.

Calling Managed Code From JavaScript :
                                                                  In order to access managed code from the JavaScript you have to do following steps.

Step 1:
          In step 1 what you have to make is the to create function (which I want to access from the JavaScript). You can do this by using ScriptableMember . So here in List 1 you can see that I have ReceiveMessageFromJavaScript function which is mark as ScripableMember. This function will called from the JavaScript and this function will take just one parameter which is of type string ( which is used to display the current time) and that string parameter is assigned to the Text proerty of the textblock which is used to show the current time on the form.
List 1

Step 2:
          In step 2 what you have to do is to registers a managed object for scriptable access by JavaScript code. As you can see in the List 1 I have used HtmlPage.RegisterScriptableObject function is used to register managed object to be access from the JavaScript. First argument is the key which is used to access the function from the JavaScript here I have used "PageName" as key and second argument is the instance name which I have pass "this".  

Step 3: 
          If you complete Step 1 and Step 2 then managed code is ready to be access from the client side mean from JavaScript. Now we have to make some changes so that we can access the managed code from JavaScript. Now is the next what you have to do is to set the id of the object which has the silverlight application as you can see in the Image 1 here I have set "silverlightApplication" id to the object which is placed inside the div tag with id "silverlightControlHost".

Image 1
The callManagdCode function is simple function which is used to set the current time as string and then pass to the managed code. Let me discuss the important code from the callManagedCode function which is started from where I get the silverlight object by using the "silverlightApplication" id and which is store in the control variable after accessing the "silverlightApplication" control by using document.getElementById next is to call the function from the managed code.
List 2

To call the managed code what you have to do is to used the control which I have store in the control variable and then use the Content and then the key name which I have set in the Step 2 and then the function name which I have set in the Step 1. As you can see in the Image 2

Image 2
At the end of the callManagedCode function I have used the setTimeOut to call the "callManagedCode()" function after every 1 second as my clock display second as well in the time so clock will be updated(if the blnStartClock is true then it will called itself after every second and update the time on the form by calling the managed code).
This how you can call the managed code from the JavaScript. I have tried my best to give full detail of how to make the communication between Silverlight and JavaScript. Hope you get idea of how to call managed code from the JavaScript.You can download the source code from here.

You can read the first part of this series from here where I have discuss how to call the JavaScript from the managed code.

All and any comments / bugs / suggestions are welcomed!

Friday, December 2, 2011

Communication Between Silverlight And JavaScript

Problem:
           While developing silverlight application there are some situation when you need to pass some information from silverlight application (which you can say managed code) to the JavaScript and also from JavaScript to silverlight application (which you can say calling managed code from the JavaScript). So in this post I will discuss how you can communicate between JavaScript and silverlight  application and vice verse.
Solution:
               I have develop simple application which display current time on the screen which you can see in the Image 1 here you can see that see I have one button which is used to start the clock and also to stop the clock. The text of  the button is changed which will return from the JavaScript function if clock is started then its text will be "Stop Clock" and if clock is stopped then button text will be "Start Clock". On button click I call JavaScript which is used to set value of the Boolean variable in JavaScript either true or false and call the function which then call managed code to display the current time on the form.
Image 1

Calling JavaScript From Managed Code:
                                                                 First I will discuss how to call JavaScript from the managed code then I will discuss how to call the Managed code from the JavaScript. First you can see the JavaScript listed in List 1 Here you can see that I have simple JavaScript function which is used to set the inverse of the blnStartClock to blnStartClock which is define globally in the JavaScript sot that other function which is the callManagedCode can used it if the value of the blnStartClock is true. Then is the value which is to set the text of the button control depending of the value of the blnStartClock mean if the it has value true then return "Stop Clock" and if the value is false then "Start Clock" string is return from the function. Which is then use to set the content property of the button control.

List 1

In the List 1 you have seen the simple of the JavaScript function which I will call from the managed code. In list 2 you can see the managed code which is used to call the JavaScript function. Here you can see that I have used HtmlPage.Window.Invoke to call the JavaScript function which you can found in System.Windows.Browser namespace (mean if System.Windows.Browser is not included in your project in the reference then you have to add it in your project).
List 2

In the list 2 you have seen that I have converted the return value from the JavaScript to string as I am return string value which is then use to set the content property of the button control. Here you can see that I have used the sender of the event as I didn't set any name to the button control. When you click the button control you will see the text on the button will changed from "Start Clock" to "Stop Clock" and from "Stop Clock" to "Start Clock". This is the simple way to call JavaScript from managed code.
In this post you have learned how to call JavaScript from managed code and also how to use the return value of the JavaScript function. In next post I will discuss how to call the managed code from the JavaScript.
You can read the second part of "Communication Between Silverlight and JavaSript" from here where I have discuss how to call the managed code from the JavaScript.

All and any comments / bugs / suggestions are welcomed!

Sunday, November 6, 2011

Display Total Records After Applying PagedCollectionView Filter

Problem :
            When we used the data grid control to show records in the tabular format, there is sometime requirement to show total number of records which are displayed in the data grid. But if you use or apply Filter to filter the records based on the user input then the number of records displayed in the data grid are changed which need to update as use changed the filter criteria.

Solution :
              For the problem above I have created simple application which contain data grid control and text box to enter the filter (which is the name of the contact person) and one text block control which is used to display the number of records in the data grid control. You can see the main page which display the data in the data grid control and the filter text box at the top along with the total record text block as shown in the Image 1.
Image 1
The code for the filter of the records is placed in the HomeViewModel class which is located in the ViewModel folder of the project. Here in List 1 I have listed important code which is used to update the total count display after the filter.  Here you can see that I have fetched record for the PagedCollectionView with name CustomerList in the constructor of the HomeViewModel and also assign filter to the CustomerList. In my post "Using PagedCollectionView Filter Using MVVM" I have assigned filter every time I need to apply filter but here I have assigned filter on the constructor mean only once. Now in the ApplyFilter function I just use the Refresh function of the CustomerList of PagedCollectionView and didn't  assign null and then again predicate to the filter of the CustomerList which I have done in my post  "Using PagedCollectionView Filter Using MVVM". The Refresh will Re-creates the view and Any Filter, SortDescriptions, and GroupDescriptions property values will be applied.
List 1

Next is to raise the PropertyChanged event for the TotalRecordCount property which is of type string and is used to display the total records displayed in the data grid control. The TotalRecordCount property has only getter which format the total records as you can see in the List 1. Now when user type in in the Contact Name text box the filter changed as I have used the behavior to update the binding every time user type some text in the contact name. You can learn more about the Updating of the binding from here which is discuss in detail why and how to use the behavior to update the binding of the text box control.
Image 2
You can see the result when user type some text in the contact name text box control. Here I have enter "an" in the contact name and you can see that total record count is also updated as I have used the filter to filter the records which start with "an" string. 
If have similar problem of updating the data grid records count then you can use above technique to solve your problem.You can download the source code from here.


All and any comments / bugs / suggestions are welcomed!


Sunday, October 9, 2011

Remove Datagrid Default Row Selection Using PagedCollectionView

Problem :
             If you have used Datagrid control then you know by default first Row of the Datagrid control is selected and if you have used the RowDetailTemplate then the RowDetailTemplate of the selected row (which is in this case is the first row) is expanded.So here we will remove the default row selection of the data grid control by using the PagedCollectionView.
Solution :
               For this example we will used the PagedCollectionView type as the item source for the data grid control and will remove the remove the first selected row which you can see in the Image 1. And I have used the MVVM pattern for this example mean I have viewModel for the home page with the name HomeViewModel.As you can see in the Image 1 when application first run and the page is loaded and the item source is assigned to the datagrid the first row is selected. Sometime default selection of the first row is fine but sometimes it is not fine as it depends on the client requirement. If client don't wants the first row to be selected then you have to implement some sort of logic so that first row of the data grid will not selected when user open the page for the first time.

Image 1
Solution to the above problem is very simple and you can see the code in the List 1. Here you can see that I have created the PagedCollectionView and assigned it to the property CustomerList which is of type PagedCollectionView. After the assignment of the CustomerList property I have used the MoveCurrentTo function which will sets the specified item to be the CurrentItem in the view.If the specified item is not found, the method returns false and the CurrentItem is positioned before the start of the collection in the view.  As you can see that I have set passed null to the MoveCurrentTo function which will return false and selection will be cleared.
List 1

Result of the List 1 can be seen in the Image 2. Here you can see that now selection of the first row is cleared and RowDetailTemplate of first row is also collapsed.
Image 2
In Image 3 and Image 4 you can see the CurrentItem and CurrentPosition of the CustomerList. Here you can see in the Image 3 that the CurrentItem and CurrentPosition properties are assigned values, mean here you can see CurrentItem has the value of type Customer which is the class I have used to populate the CustomerList of PagedCollectionView type and the CurrentPosition have 0 value mean first row is selected.
Image 3
But after calling the MoveCurrentTo for the null value the values for the CurrentItem is null and CurrentPosition is -1 mean no row is selected now for the PagedCollectionView. The CurrentItem and the CurrentPosition properties are the read only properties mean you can't set value for these properties you can get value of the CurrentItem and CurrentPosition properties.
Image 4
I have used MoveCurrentTo function of the PagedCollectionView, if you have used other function or technique which is better then this then please do let me know about it by sharing your technique or logic here will help not only me but also other who come to this post if they have similar sort of problem or requirement. You can download the source code from here.

All and any comments / bugs / suggestions are welcomed!

ContextMenu using MVVM

In this post we will discuss how to use the ContextMenu using MVVM pattern. You can find the beginner level of article about how to use ContextMenu on the web. But here I will show you how to use it using MVVM pattern. This is also first time that I am using the ContextMenu control of the Silverlight. So if there is any error or if you feel that I have miss something related to the ContextMenu then please let me now about it.
For this example I have used the Text Box control when you right click on the text box it will display the ContextMenu in the Text Box control. As you can see in the Image 1 when user right click inside the Text Box control Context Menu open  with the cut, copy and paste option in it. Here you can also see that I have also place TextBlock control with text "Message will be displayed here" which will show you the menu item click concatenated with the Time.
Image 1

In List 1 you can see the xaml to add the Context Menu in the Text Box control. Here you see that I have used Silverlight toolkit ContextMenuService which will handle the event and positioning of the ContextMenu and I have placed it inside the Text Box control. Here you can see for every menu item I have set the Header like Cut Text, Copy Text and Paste Text which you will see as label as see in the Image 1 and also you can see that I have also use the icon property of the menu item to show the icon for every menu item.

List 1

If you don't want to show icon for any menu item then you can remove the icon property. After setting the header and the Icon property of the menu item next is the binding of the command to the Command property of the view model. Here I have used only one command for all the menu item which is the MenuClickCommand and in the CommandProperty I have passed some text which will identify the sender of the click event as in the code behind we can identify it by converting the send of the event but as in case of command we can't have UI information so I have used the CommandParameter for every menu item so that I can Identify send of the event.
Image 2
When user click any of the menu item text is update to show which menu item is click and when it is clicked (mean the time stamp) which you can see in the Image 2 the message are highlighted. You can perform what action you required when any of the menu item is click. I have simply show text in the main page to show the menu item click you can perform operation like cut , copy paste or even save, update , edit and cancel operation depending on your requirement.You can download the source code from here.

All and any comments / bugs / suggestions are welcomed!

Saturday, September 17, 2011

Applying Pageing and Sorting on ListBox Control

Background :
                    If you have ever used the data grid control then you are familiar with the sorting functionality which is provided by default, when you click any of the data grid header then it will sort the records according to the that column name on every click it will sort it ascending or descending direction. Similarly you are familiar with the data pager control which we often used with the data grid control to show record in the form of page which contain specific page size.It was one of the question which one of my colleague ask me "Can we apply paging to the List Box control ". As I didn't use data pager control other then data grid so in this post I have used the data page control and also the sorting which is provided by the PagedCollectionView.

Solution:
                For this example I have the application which you can see in Image 1, Here you can see that I have used combo box control which is used to sort the list box control item in ascending or descending order, List box control to display the records and the data pager control for the paging purpose.

Image 1

The use of paging is very simple it is just same as you do with the data grid control. Just place the data pager control in the xaml and set the Source property of the data pager to the list or collection which is used to bind the list box control, here you can see if I remove the data pager control then it will display all the record of the collection/list as you can see in the Image 2. So paging is quite easy similar to the data grid paging.

Image 2
Second part which is used to sort the items in the list box control is easy as well but you need to do some coding for it. For this I have done some coding in the view model of the home page which you can see in the List 1 here you can see I have posted whole view model as it is small view model not very large amount of coding in it. In the code you can see I have only two properties one is the PersonList (which is of type PagedCollectionView type which is used too bind the list box control ) and second one is the SortDirection property of type string ( which is used to sort the list box item according to the one of the value either ascending  or descending which are display in the combo box as inline items ).

List 1

In the constructor I have populated the PersonList PagedCollectionView by calling GetPersonRecord function of the person class ( the person class has on one property , the name property which is of type string and hold the person name). The main functionality of the sorting is done in the SortDirection property where I have used the SortDescriptions property of the PagedCollectionView to sort the records in the List.SortDescriptions collection of PagedCollectionView describes how items are sorted in view. SortDescriptions is a collection in which we can add more than one sort field. But here in our example as I have only one field which is the name field so I have first clear the SortDescriptions and then add the new sort direction, if you have more then one direction to sort the record then you don't need to call the clear function of the SortDescriptions you just add the new field in that and it will perform the sorting according to the field name which are provided in the list.We add sort field by adding SortDescriptions that specify which property will be used for sorting and the direction(ascending or descending order). When user select Ascending from the combo box then item are sorted from A to Z direction which you can see in the Image 3.

Image 3
When user select Descending from the combo box then item are sorted out from Z to A direction which you can see in the Image 4.

Image 4
I have tried to used the paging and sorting in the list box control and also tried to explain you how you can used it in your code if you have requirement to sort the list box control, you can event it it without giving the control to you user like I have provided the combo box and provided two option ascending and descending. You can download the source code from here.

All and any comments / bugs / suggestions are welcomed!

Friday, September 16, 2011

SelectedItems Using PagedCollectionView Using PropertyChanged

In my post "Get SelectedItems From DataGrid Using MVVM In Silverlight " I have used command and triggers to get the selected items of the datagrid control. Here we will get the selected item of the data grid control without using the command and trigger. Here we will use the PagedCollectionView to get the selected items. So that we can remove the use of the command and the triggers which we have used in the "Get SelectedItems From DataGrid Using MVVM In Silverlight" post and we will take advantage of INotifyPropertyChanged interface.

Solution :
           The solution is very simple as we don't want to use the command and the triggers but we want to achieve this on the property changed which you can achieve by implementing the INotifyPropertyChanged interface. The main page which we are using for this example is shown in the Image 1, here you can see that I have two similar data grid controls on the left side the source data grid control which is populated when the page is loaded and on the right side is the destination data grid control which will display the selected items from the source data grid control.

Image 1

First I would like to discuss the Persons class which I have used for this example which is listed in the List 1. Here you can see that I have inherit the Persons class from the INotifyPropertyChanged interface and also implemented the INotifyPropertyChanged event handler which you can see at the end of the class.I have First name, Last name, city , country and Is selected properties in the class. You can see that I have only raise the PropertyChanged event from the Is selected property as this proper is of type Boolean and I will perform selected of the record based on the true/ false value of IsSelected property. If IsSelected property has value true then record is selected else record is not selected.
List 1

Note: In List 1 I have only shown relevant which I wan to discuss here, function which return sample records has been removed but you can find the function on the sample application which you can download from the link which is provided at the end of the post
In the List 2 you can see the viewModel for the Home page which is used as the data context for the home view.Here you can see that I used two properties one is PersonList which is of type PagedCollectionView and used for the first gird which is place on the left side of the interface and which will be the source datagrid from where you can select record by clicking the check box control which is displayed in the first column of the data grid control.
List 2

Second property which is ObservableCollection type will hold the records for the second datagrid control which is shown on right side and act as destination and will only show records which are selected from the source datagrid and you can only view records in the destination data grid as the check box control property isEnabled is false and IsReady only property of the datagrid is also false. In the constructor I have initialized the PersonList which is of PagedCollectionView type by call the Persons GetPersonRecord function which is the static function and will return List of Persons( which you can find in the Persons class in the downloaded example code). In the next statement I have use foreach loop to attached the PropertyChanged event of the record as I have used the INotifyPropertyChanged interface in the Persons class So  I can now I have PropertyChanged Event for each record.
When you click any of the check box control in the source data grid the PropertyChanged event which is attached with every record and IsSelected property in the Persons class has raise the PropertyChanged event when the value is changed. In Image 2 you can see the sender and the arguments of the events here you can see that in the sender it will show you the whole record and in the arguments it will send the property name which is changed.In the argument 'e' there is name PropertyName which hold the name of the property here you can see that it has "IsSelected" as I have raised the event from IsSelected property.
Image 2

In the PropertyChanged event I have cost the sender to the respective type in this case my class name is "Persons"  so I have created object of type Persons and save the sender in that object. Then in the next statement I have check for the IsSelected value if the value is true then I have added the sender to the SelectedList property which is used to bind to the destination datagrid to show the selected item.

Image 3

When you select records from the source data grid then you can see the selected item in the destination datagrid. For tested purpose I have selected random 3 items from the source data grid and the selected items are shown in the destination data grid as shown in the Image 3 above. If you unchecked the any of the selected record then that record will be removed from the destination datagrid.You can download the source code from here and also test yourself.

Note: In the Persons class you have seen that I have only raised the PropertyChanged event from the IsSelected property because I want to do procession on the basis of the IsSelected property value. If you changed any of the property like First name, Last Name, Country and city then PropertyChanged event will not fires as these properties didn't raise PropertyChanged event in the setter.


All and any comments / bugs / suggestions are welcomed!

Sunday, September 11, 2011

Using PagedCollectionView To Group DataGrid Records Using MVVM

Problem :
          When using data grid control sometime we provide grouping of data so that user can see records in groups but the groups are predefine and If you don't want to see the group which we the developer or the client provide then he/she can't change. So here  we can use approach to provide the grouping of data to the end user if he/she want to see the data grid records in groups then he/she can arrange records in groups but if he/she don't want to see the he/she can remove the grouping of records.

Solution :
             Solution for the above problem again is in the use of the PagedCollectionView type and the sample application which is used for this is shown in the Image 1, here you can see that I have combo box with contains the columns name like I have place country and city which are used to group the data grid records. and one check box control which I will explain when I will discuss the code used to group the datagrid control.


Image 1

Code used to group the data grid record into group is show in the List 1, here you can see that I have function with name ArragePersonListByGroup which is called from the two separate location. In the viewModel I have define two properties one is the GroupBy which is of type string to hold the name of the by which we will group data grid records and in the setter of the GroupBy I have called the ArragePersonListByGroup function so that whenever user change the name from the combo box the grouping is changed.Second property IsNestedGroupAllowed which is of type Boolean type is used for the nested group mean if user want to see first group by country name then in the country he/she want to group by city then user first checked IsNestedGroupAllowed check box then nested grouping is done but if the IsNestedGroupAllowed is unchecked then nested grouping is not done only one level of grouping will done.

List 1

In the ArragePersonListByGroup function you see the first statement is to check the GroupBy property name to not equal to the "Select Column Name" mean if user select this option then he/she want to remove the grouping from the data grid records as the else statement you can see that I have clear the GroupDescriptions of the PersonList (which is of PagedCollectionView). For grouping we have used the GroupDescriptions property of the PagedCollectionView which provides a base class for defining how to divide the items in a collection into groups. After checking the GroupBy value to not equal to the "Select Column Name" again If condition is placed to check the IsNestedGroupAllowed ( to check if the user want to multiple level of grouping or not ) property and the null value ( as if no value is selected when application start then GroupBy has null value). First I have not checked the IsNestedGroupAllowed check box so the else part is executed where GroupDescriptions property of the PersonList (which is of PagedCollectionView type) is clear so that if any GroupDescriptions is already added then it should be removed and the new one will be added in the next statement. Now when user select column name from the combo box and check box Nested Group is unchecked then you can see the output in the Image 2.

Image 2

Now if user changed the column name from Country to City then grouping will be on the basis of the City name of the records and if user select "Select Column Name" then grouping will be clear.
Now the next case when user want multiple level of grouping in the records which you can see in the Image 3, here you can see that Nested Group checkbox is checked and first I have select country and then city from the combo box. You can see that first records are grouped in country name and within the country name the records are grouped with city name.

Image 3
The code for the multiple level of the grouping is listed in List 1, here you can see that if the IsNestedGroupAllowed property is true (when user checked the Nested Group checkbox from the UI) and GroupBy property is not null or empty is false. In the if condition is true mean user want multiple level of grouping then first I have check the GroupDescriptions collection if the selected GroupBy is already exist in the GroupDescriptions list or not if GroupBy is not already added then add the GroupBy in the GroupDescriptions collection.

Note : Here you have to check the group name if you didn't check for the already added group then it will add group multiple time as many as you have added it, So it is better to check as I have check in my code so that one group is added once if user selected it multiple times.

I have provided only two level of grouping of the records if you have more columns then you can provide it to more level of grouping.It is better to give as much functionality to end user as if he/she want to see the records in groups , he/she can arranged it into groups and in to multiple level as well.You can download the source code from here.

Note : You have to check for the null value of the group name if you didn't set the default value of the combo box (in my case I have used combo box to show column names) when application run and end user directly check the Nested Group check box (as no column is selected at that time, then a group with PagedCollectionView_Group.Model.Person (Person is the class name of the collection which I have used) is added.
All and any comments / bugs / suggestions are welcomed!

Saturday, September 10, 2011

Using PagedCollectionView Filter Using MVVM

Problem :
          When using data grid control there may be large amount of records in the data grid and to find out record which user is search is very difficult as he/she has to view every record to find out the desired record. So it is nice idea to have filter on the data grid records so the user can filter data grid records and find what he/she is looking in the data grid records

Solution :
          To provide the end user with some sort of filtering of the datagrid record we will use the Filter property of the PagedCollectionView. Example which is used for the filter property of the PagedCollectionView is shown in the Image 1, here you can see that I have used checkbox control to filter the active and in-active records in the datagrid control, combo box control to provide the searching of the First name in the data grid control and it has 3 values StartWith which is used to find the text entered in the text box at the start of the first name in the list, EndWith which is use to find the text entered in the text box at the end of the first name and 3rd one the Contains checks whether the specified text box  character combination occurs within first name. And the text box control used to entered any combination of character to search in the first name of the record.

Image 1

Code used for the filtering of the datagrid record is shown in the List 1. Here I have listed imported code which is only used to filter the record not the properties of the viewModel. In the viewModel I have null-able Boolean property for the Active which hold the value true ( active record), false (for in-active record) and null ( for all records). FirstNameOperator property which is used to hold the string value for the comparison of the first name property like StartWith, EndWith and Contains are the values which are shown in the combo box are selected in the FirstNameOperator. And FirstName property which is used to hold the user input for search the search first name.
List 1
You will notice that, the PagedCollectionView has a property called “Filter” which takes Predicate. The predicate will take callback which will provide the filtering logic. This callback method examines each row and indicates if the row should be included or excluded by returning true or false. Here, our PagedCollectionView is our collection named “Customer”. First of all set the Filter of this collection to null to remove the previous filtering. Then set a new Predicate function call to it.
The callback function FilterCustomerList takes the object first we need to convert the object to corresponding type here in our case as our PagedCollectionView is of type Customer so we need to convert it to Customer type.Next I have check for the active or in-active record if the value of the IsActive property is not null as in case of null we don't need to see the active or in-active records.If value is not null and the currentRecord which is passed to the callback , if Active property is not equal to the value of the IsActive then return false mean I don't want to include this record in the final output. I have used the false value to exclude the current record from the final list as you can see that at the end of the callback I have return true to include the record in the final list.When user checked or unchecked the checkbox the output is similar to the what has be shown in the Image 2, here you can see that only active records are shown as checkbox is checked, if you unchecked the checkbox then in-active records are shown.
Image 2

Second filter criteria which is the to filter by first name of the customer.The first name of the customer is the string type so we need to perform string operation on the first name field of the customer record.To check the first name of the customer I have created separate function to check the first name of the customer record which take the customer record and then perform the string operation like start with, end with and contain. Here you can see that I have used blnIsValid of type Boolean and set it to false mean record is not matched and will be excluded from the list. Then I have check the FirstNameOperator property to perform what user want to check in the first name first name field, mean user want to say e.g If use enter 'e' character in the text box and want to see the records which are start with the character 'e' then he/she will select StartWith operation, or user want to see the record which are end with character 'e' then he/she will select EndWith from the operation or if he/she want to see customer records which contain the character 'a' then he/she will select Contains operator. Output of the filter when user filter by first name is shown in the Image 3, here you can see that I have not used the active filter criteria.

Image 3
The final output when user use both active and first name criteria is shown in the Image 4, Here you can see that I have use the active records and then I have used the Contains operation for searching in the first name of the customer record and I have entered character 'e' to search in the first name. In the Image 3 you can see that I have search the records by entering the character 'e' in the text box control and used the Contains operator and we have total 5 records displayed in the Image 3 one is in-active and remain 4 are active records. And in Image 4 you can see I have only select the active record by checking the checkbox and the first name criteria is same as I have used in the Image 3.

Image 4
Hope you get idea of how to filter the data grid records when you have large amount of records are showing in the data grid control, by providing the filter criteria to filter the records end user can find the desired record quickly and hence he/she can save his/her time which he/she has to spend in order to search the specific record in the data grid control.You can download the source code from here.

All and any comments / bugs / suggestions are welcomed!

Sunday, September 4, 2011

Make a Silverlight TextBox update its binding on every character

Problem :
              One of the problem which I have faced during my learning and working in MVVM pattern and one of requirement when you have provided the search box as user type in some character in text box control you want to show results in the data grid control. But in silverlight there is only two option when you bind a property to update the source Default and Explicit. There is no PropertyChanged option which is provided in the WPF.

Solution : 
              For the problem I have created sample application to discuss how to get this working if you have similar situation mean there may be requirement from your client to provide such functionality mean as client type in some character the result should displayed in the some control link datagrid which I have used. In the example I have used one text box control ( for user to type contact name ) and a datagrid control to show the matching result of the user search. You can see the layout of the example in Image 1, I have home page which contain the problem and the working example which is working fine as user type in character in the text box matching results are filtered in the data grid control.

Image 1
Example 1:
                For example 1 which is shown in the Home page link you can see I have used the normal binding of the text box control. The code for the first example is shown in the List 1. Here you can see that I have not set UpdateSourceTrigger which is default mean when control lost focus then latest value is send back to the view model as binding mode is TwoWay.  I have created two view models for home and the Working Example view but the code is nearly same in both view models. The change will be in the xaml of the both the views.

List 1
Example 2: 
             For Example 2 which is shown in working example page link here you can see  as user is typing in the contact name text box records in the datagrid are filtered.The xaml code for the Example 2 is shown in the List 2. Here you can see that I have used the Behavior for updating the source whenever user type in some character in the text box.


List 2

Note: I have also tried to use the event trigger to solve this problem but in event trigger the problem is it didn't send last character entered by the user. For exam if user enter character 'AN' then it will send 'A' back to the source not 'N' which is the last character entered by the user. That is why I didn't use that solution as end user will not get latest result because of last character exclusion. 

By using the above technique mean using the Behavior my problem of filtering the record on every key press was solved hope if you have requirement like this you can use same technique to solve it.You can download the source code from here.

All and any comments / bugs / suggestions are welcomed!