Tuesday, May 4, 2010

Making Telerik RAD Grid Hierarchy at your ease

Hello,
Continuing with the topic on Telerik RAD Controls, I am herewith presenting few of my experiences on RAD Grid Hierarchy.This will greatly help reduce your time on the same.
  1. Telerik RAD Grid Hierarchy.
    It’s very simple to create a hierarchy using Telerik RAD Grid but there are few properties, events that we need to understand to make it work as desired.
    RAD Grid contains MasterTableView and Detail Tables using which hierarchy can be created by just providing a parent table relationship. It is obvious that the hierarchy can only be created with a relation between two tables.
    Master Table View:
    For e.g.: Consider the following snippet:
    AllowSorting="True" AutoGenerateColumns="False" PageSize="5" BorderWidth="0px"
    OnNeedDataSource="rgd_DataSource" OnItemDataBound ="rgd_ItemDataBound" OnDetailTableDataBind="rgd_DetailDataSource"
    OnItemCommand="rgd_ItemCommand"
    MasterTableView-ExpandCollapseColumn-CollapseImageUrl="~/images/Content/arrow_expanded.gif"
    MasterTableView-ExpandCollapseColumn-ExpandImageUrl="~/images/Content/arrow_collapsed.gif">



    PagerStyle-AlwaysVisible="true" CommandItemSettings-AddNewRecordText="Add New "
    AutoGenerateColumns="false" CommandItemDisplay="Bottom" Name="" DataKeyNames="Id,MemoryId,Title,Name,BusinessTitle,Purpose,Fax,Email,Phone">

    Master table View is bound at higher level of hierarchy. Data source of any kind can be bound here. It’s mandatory to define the DataKeyNames array. This holds all the fields or columns of the data source that is bound in this mastertableview.
    The RadGrid control has a MasterTableView property that represents the top table in the grid. The instances of RadGrid and MasterTableView are almost identical, although they are of different types (RadGrid and GridTableView, respectively).
    The main difference between RadGrid and MasterTableView is that the properties of RadGrid specify the defaults for every GridTableView in the grid (the MasterTableView and any DetailTables). The properties of MasterTableView apply only to the top-level table in the grid. In other words, property settings on MasterTableView are not inherited by any DetailTables nested inside it. The properties of MasterTableView, as with the properties of any DetailTable in the grid, act as overrides to the defaults set on the RadGrid object.
    For example, if we set blue border for the RadGrid object, the MasterTableView and any DetailTables will also have blue border (assuming they do not override the property setting), while if we set blue border for the MasterTableView, this border will appear only on the top-level table, and not on any detail tables.
    ?Always define Common attributes that need to apply to entire Grid including master and detail tables, Define them in Radgrid. We can also apply mastertable attributes in RAD Grid using prefix of mastertableview-commandItemDisplay etc. But it’s always better to define attributes of mastertableview and radgrid or any detailtables in their respective places which makes more readable and understandable.
    Grid Table View: There is one Grid Table View for each Detail Table in the grid. Grid Table View need to be bound to a datasource as we need to ensure that each Grid Table View in the grid has its own table within parent table.
    All the detail tables are added to Detail table collection as shown in following snippet:

    CommandItemDisplay="Bottom" CommandItemSettings-AddNewRecordText="Add New A"
    AllowPaging="false" HierarchyDefaultExpanded="false" DataKeyNames="TemporaryId,TempId,APurpose,A1,A2,PostalCode,City,CountryName">




    As we see in the above example, Details Tables contain a Grid Table View; each table is defined as a level in hierarchy.
    ?Make a thumb rule to define the columns of inner most table of hierarchy first in detailtables collection..Parent table relation must be defined as the hierarchy occurs.
    Ensure that each table in the grid has its own data source
    If we are using declarative data sources, set the DataSourceID property of each table to the ID of a DataSource object. For each parent table, set the DataKeyNames property to an array containing the names of each field in the table's data source that is used to link to detail tables. For each detail table, add GridRelationFields objects to the ParentTableRelation collection, each of which specifies a link between a field in the detail table to a field in the DataKeyNames array of the parent table.
    If we are not using declarative data sources, add event handlers for the NeedDataSource and DetailTableDataBind events. In the DetailTableDataBind event handler, we can determine which data source should be related to the current table view by checking whether the GetDataKeyValue method of the detail table's ParentItem returns a value.

    ?Hierarchical structure is not supported with simple data-binding (calling DataBind()).
    We cab dynamically bind the Grid properties by just declaring the RAD Grid statically. We can define the structure of a RadGrid control that is declared in the ASPX page, by using the Page_Load event handler. Columns and detail table should be added to the corresponding collection first, before the values for their properties are set. This is important because no ViewState is managed for the object before it has been added to the corresponding collection.

    ? Be sure to check that IsPostBack is false. Otherwise, we will end up adding the same objects to the RadGrid multiple times.
    We can also create the RAD Grid with its hierarchy dynamically. To generate RadGrid instance entirely in code, we should use the Page_Init event handler. Once the grid is created, add it to the Controls collection of a PlaceHolder control that is declared in the ASPX file. When generating a grid in the Page_Init event handler, grid columns should be added to the Controls collection of the MasterTableView after their attributes are set. No ViewState is required for grid structure to be persisted as it is recreated on each page initialization.
    Parent Table Relations: We need to define the ParentTableRelations and DataKeyNames for the MasterTableView and GridTableViews according to the database relations conventions. And here are the exact conventions:
    the primary key column name for each table in the grid source (used for master/detail table population) should be added to the DataKeyNames collection of the respective master/detail table
    the MasterKeyField in the GridRelationFields should match the primary key of the parent table in the corresponding relation
    the DetailKeyField in the GridRelationFields should match the foreign key of the child table in the corresponding relation
    There is one more detail if we use declarative binding using DataSource controls.We should have WHERE clause in the SelectCommand of the data source controls for the nested tables which to filter the records for them. The WHERE clause should include the field from the ParentTableRelation definition between the master/child table. Furthermore, that same field has to be included in the SelectParameters of the "inner" data source controls (with exactly the same Name and SessionField value). An important detail is that every GridRelationFields should have only one field name for DetailKeyField and MasterKeyField. For multi-hierarchy relations we can use multiple relation fields as in the example below:


    ?ParentTableRelation must be properly and correctly defined else the detail table or inner level data will not be loaded and there would be no proper error message or exception thrown.
    Events: Inorder to bind the Mastertable and Detailtable, the following two events need to be handled.

    OnNeedDataSource: This event is handled to populate the RadGrid MasterTableview with data. It gets fired when the grid is about to be bound with the data source that is assigned (is null/Nothing).

    Using this event eliminates the need for calling
    RadGrid.DataBind when the grid content should be refreshed, due to a structural change.For example if Edit command bubbles, grid will automatically rebind and display the item in edit mode, with no additional code.
    When we use NeedDataSource we need to assign manually the DataSource property only once in the event handler!

    We should never call Rebind() method in NeedDataSource event handler or DataBind() for the grid at any stage of the page lifecycle!
    Following are the cases when this event is fired inorder to help us understand when the grid is fetched for data:
    . Right after OnLoad - if the grid has not been data-bound yet and there is no ViewState data.
    This also means that if MasterTableView.DataSourcePersistenceMode has been set to NoPersistence, grid would bind each time the page loads (not only the first time);
    When paging operation occurs.
    When sorting operation occurs.
    When Edit command is fired.
    Right after Update/Delete/Insert command event handlers finish execution. You can cancel these operations handling ItemCommand event and assigning false value to the e event argument's Canceled property.
    When grouping / ungrouping - right after the RadGrid.GroupsChanging event is raised;
    When filtering (choosing an option from a column filter menu);
    When resorting a group.
    When a call to the Rebind() grid method takes place.
    Prior to any detail table binding.

    DetailTableDataBind: Fires when a detail-table in the hierarchy is about to be bound. You should only assign the DataSource property of the detail table to a data-source properly filtered to display only child records related to the parent item. We can find the instance of the detail table in the event argument (e). We can find the parent item using e.DetailTable.ParentItem property.

    Eg:
    protected void rgd_DetailDataSource(object source, GridDetailTableDataBindEventArgs e)
    {

    GridDataItem dataItem = (GridDataItem)e.DetailTableView.ParentItem;
    int selectedMemoryId = Convert.ToInt16(dataItem.GetDataKeyValue("MemoryId").ToString());
    int selectedId = Convert.ToInt16(dataItem.GetDataKeyValue("Id").ToString());
    if (ViewState[ViewStateConstants.OBJECT] != null)
    {
    try
    {
    Entity = (IList)ViewState[ViewStateConstants.];
    ViewState[ViewStateConstants.] = Entity;
    if (selectedId == 0)
    {
    foreach (Entity tempEntity in Entity)
    {
    IList aEntity = new List();

    if (tempEntity.MemoryId == selectedMemoryId)
    {
    aEntity = tempEntity.A;
    e.DetailTableView.DataSource = aEntity;
    break;

    }

    }
    }
    }

    catch
    {
    lblMsg.Text = "Unable to load";
    }
    }
    }

    Handy Properties / Methods :
    It is always better to name each table like MasterTableView or Detail Grid Table view to identify in code behind to handle the logic, e.Item.OwnerTableView.Name can be used to compare the name of the table that is provided.
    GridEditableItem editedItem = e.Item as GridEditableItem;
    editedItem.GetDataKeyValue("MemoryId");
    The above lines are used to retrieve the column value of Column “MemoryId” provided this key is defined in DataKeyNames array while creating the MasterTableView.

    GridDataItem dataItem = (GridDataItem)e.DetailTableView.ParentItem;
    int selectedMemoryId = Convert.ToInt16(dataItem.GetDataKeyValue("MemoryId").ToString());

    The above lines are used to retrieve the value of column of “MemoryId” while loading detail table and parent or mastertable parentkey is required to filter data. This can be used in the event DetailTableDataBind.
    To hide the commandItemDisplay in the grid this needs to be handled in ItemDataBound event. Following lines hides them in both MasterTable and Child table:
    rgd.MasterTableView.CommandItemDisplay = GridCommandItemDisplay.None;
    rgd.MasterTableView.DetailTables[0].CommandItemDisplay = GridCommandItemDisplay.None;

    We can hide the edit or delete columns which again needs to be done in ItemDataBound event. Following lines of code demonstrates them for detail table:
    GridColumn editColumn = rgd.MasterTableView.DetailTables[0].GetColumn("TemporaryId");
    editColumn.Visible = false;

    GridColumn deleteColumn = rgd.MasterTableView.DetailTables[0].GetColumn("Deletecolumn");
    deleteColumn.Visible = false;

    Key string provided in GetColumn method is the uniquename provided as shown below in html code:



    Refresh and Rebind buttons can be hidden by using the following snippet:
    GridCommandItem cmditm = (GridCommandItem)e.Item;
    cmditm.FindControl("RefreshButton").Visible = false; cmditm.FindControl("RebindGridButton").Visible = false;
    Conclusion: There are many more properties and methods which can be explored on the same lines as explained above. This documents can be used handy to create a hierarchy using Telerik RAD Grid. Self Referencing Hierarchy works in a different way in Telerik RAD Grid which I would document soon to help you better.
    Happy Coding & Exploring !

Wednesday, January 20, 2010

Telerik RAD Grid

Its been long writing here as friends became quiet busy with personal life....
Finally got to do some interesting work and hence found something to share with you all.
The problem is how would you create a Hierarchy of data (something which shows of hierarchy of staff in an organization) with in a grid , say it could be ListView, DataGrid, Gridview etc...
One thing comes to our mind is to use the nested controls and create them dynamically as and whenrequired.
Very true, I can place the ListView, DataGrid, orGridview within a ListView, DataGrid, or Gridview and show them accordingly. But do we know how much would the depth of the tree be and how many controls do you have to define at design time.
And What kind of coding complexity might come to you to get this done?
So, finally I switched to RAD Controls for the same feature is available at the below link with an example:
http://www.telerik.com/help/aspnet/grid/grdselfreferencinghierarchy.html
And it worked so cool that the development time was also too less...
Just get the code as required but the following fields are important:
MasterTableView HierarchyDefaultExpanded="true" HierarchyLoadMode="Client" EnableNoRecordsTemplate="false" DataKeyNames= "ID,ParentID" Width="100%">
DataKeyNames attributes are the one table columns which are used through in the Grid Query and to use RadGrid1.MasterTableView.FilterExpression
ParentKeyName is the column to find the root of hierarchy and KeyName is the column which is associated with parentId.
You can enable expand and column hierarchy by just making the property ClientSettings AllowExpandCollapse="true" />
Inorder to make the columns width fixed as you collapse, make the property as : would show the pager only for master data instead of hierarchical data and columns are fixed in lenght as and when you expland the tree structure.
And one more thing, if you want the header to be shown for child records,
You need to tweak some code as follows:
if (e.Item is GridHeaderItem && e.Item.OwnerTableView != Grid1.DetailsView) { e.Item.Style["display"] = "none"; }
in the RadGrid_itemcreated event.
This was quite interesting to do with less effort and much more productive work.
Note that using trial version of Telerik may not work as expected or documented in telerik site, so use the developer version of the controls.
Happy Coding....

Saturday, November 15, 2008

Inactive Connections in Oracle9i

Few days ago, there was a strange problem I came across in my site. The site was down displaying " TNS listener couldnt be found" and on analyzing, we found that there were already 150 connections to database and hence has to increase the connections to 300. But this dint solve the problem? There were both active and inactive connections to database wherein inactive connections were not getting closed automatically. Ideally speaking, they should be closed if there is no transaction or query procession done.
On further analysing, a new issue was known to me that .Net Data provider when connected to Oracle, keeps the connections inactive or idle connections. A workaround for this issue recommended by Microsoft was to kill the asp.net worker processes manually, but even this couldnt be an ideal solution.
This problem was fixed in Oracle Data Provided Provided by Oracle Corporation which works with .Net Framework with service Pack 2.
Hope this helps you too.

Friday, October 31, 2008

PERFECTION IN DEVELOPMENT...

Can a developer be perfect in her development?
Is there a need to be perfect in it?
Who is responsible for bugs hindering the perfection?

Business Value of Virtualization.

Virtualization is getting more and more popular these days. Obviously, there is a lot of value to adopt this in the infrastructure. But what would these add in for a Business?




  • Adopting a simple virtualized infrastructure can result in a reduction of up to 35%
    of total annual server costs per user compared with an unvirtualized static x86
    server configuration. It is commonly applied to test and development environments, along with at least some production use.



  • Research finds that the use of more advanced virtualization technology, along
    with increasingly sophisticated systems management tools that manage both the
    guest environments and the virtualization engines themselves, can further extend
    the benefits of virtualization significantly.



  • An optimally managed or "advanced virtualization" infrastructure, described as an
    infrastructure that includes penetration of virtualized servers of more than 25%,
    storage virtualization, and the use of systems management tools, can deliver a
    total reduction of up to 52% per user per year.


There are three types of deployment:
1. Unvirtualized . physical x86 server/physical OS usage/no virtualization and
systems configured at less than 10% capacity
2. Basic virtualization . x86 server consolidation via virtualization without
advanced functionality such as live migration and with limited automation and
management applied selectively; systems achieve from 20% to 40% capacity
utilization; common deployment for test and development scenarios, but limited
production use
3. Advanced virtualization . widely virtualized infrastructure (>25%), including
both server virtualization and at least some storage virtualization; use of
management tools and automation tools such as workload redistribution and
automatic workload migration . used both on live VMs and on cold OS images
. for meeting service-level agreements and availability goals; systems achieve
40% to 60% or more capacity utilization.




By so doing, organizations will gain better utilization of server resources and reductions in
acquisition, deployment, and power and cooling costs.
Further, the reduction of staffing costs and increasing business agility translate into
long-term benefits that for years to come will deliver ongoing returns on the
investment required to put this in place initially.