Ok this one was not immediately obvious to me so I’m posting the solution here. I’m using a Telerik Ajax RadEditor on my page as follows:
<telerik:RadEditor ID="rhfNotes" EditModes="Preview" runat="server" ToolsFile="ToolsFile.xml">
</telerik:RadEditor>
Now, after doing a bit of inspection, I discovered there was a property I could set on the RadEditor called ToolTip that seemed to just require a string value as follows:
<telerik:RadEditor ID="rhfNotes" EditModes="Preview" runat="server" ToolTip="Some message to the user" ToolsFile="ToolsFile.xml">
</telerik:RadEditor>
I assumed this would produce exactly what I needed. Unfortunately, after testing the above out, I got nothing, no tool tip. Doing a search on the forums turned up nothing useful, not even an explanation as to what the ToolTip property was really for. However, I did come across an entirely separate control in the Ajax suite of controls called RadToolTip.
That’s clever I thought, perhaps I’ll just give that a go. I was hoping there would be some sort of property I would set that would allow me to specify what control to tie this tool tip to. Guess what! There is! My final solution was as follows:
<telerik:RadToolTip ID="rttNotes" runat="server" TargetControlID="rhfNotes" Text="Some message to user"></telerik:RadToolTip>
<telerik:RadEditor ID="rhfNotes" EditModes="Preview" runat="server" ToolsFile="ToolsFile.xml">
</telerik:RadEditor>
There you have it. I haven’t played around with all the properties and options I have available to me with the RadToolTip, but I’m sure there are some useful ones in there!
Let’s say you have 2 RadGrids defined in your aspx page. Both grids happen to share the same ItemDataBound event, but you’d like to apply a small tweak depending on what grid is calling the ItemDataBound method.
In order to implement your tweak, you’ll need a way to find the ID of the grid that made the call. And not the ASP.NET generated ID, since that can be rather ugly, but the ID of the control you created in the aspx page. The following example demonstrates how this can be achieved:
1
2
3
| <radG:RadGrid ID="rgThisYearsItems" runat="server" OnItemDataBound="rgItems_ItemDataBound"></radG:RadGrid>
<radG:RadGrid ID="rgLastYearsItems" runat="server" OnItemDataBound="rgItems_ItemDataBound"></radG:RadGrid> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| protected void rgItems_ItemDataBound(object sender, GridItemEventArgs e)
{
// we need to determine what grid is calling the itemdatabound event
RadGrid grid = (RadGrid)e.Item.OwnerTableView.OwnerGrid;
if (grid.ID == "rgThisYearsItems")
{
// perform some logic here
}
if (grid.ID == "rgLastYearsItems")
{
// perform some logic here
}
} |
The reason you might want to implement the above is for code reuse. If you’ve got two grids and the ItemDataBound event for both will be really similar minus a line or two, you can have them both call the same ItemDataBound event and use the above logic to determine when to run the custom pieces.
Thoughts?
So here’s the idea. I’ve got a RadGrid on my page that is populated programmatically. I build a DataTable from various different sources and once I’m satisifed with how my DataTable looks, I set the grid’s DataSource property and bind.
That’s all good, except now I want to insert a header row in the middle of my grid. The idea behind this row is to simply provide a clear segregation between my different sources of data. It’s all one grid remember, but I wanted a way to distinguish between the data.
I came up with the idea to simply add a header row at the point I needed, set the ColumnSpan to match the number of columns I have in my grid, set the HorizontalSpan to center the text and finally set the Visibility on all other columns to false.
Here is what I ended up with. The grid is setup with 5 columns: Name, Address, City, Province and Country. At the point where I’d like my see my header row in the grid, I set the Name column to the text I’d like the header to contain. Keep in mind that I have rows being added before and after the code sample below. I’ve inserted the code exactly where I want my header to appear:
1
2
3
| DataRow row = dt.NewRow();
row["Name"] = "My heading that I'd like to show";
dt.Rows.Add(row); |
Now in the ItemDataBound event, I can modify this particular row that I just created so that it spans all the columns and is centered as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
{
if (e.Item is GridDataItem)
{
GridDataItem dataItem = e.Item as GridDataItem;
// i use the second index to get at the name column. the first two indexes
// are empty for me and don't contain any valuable data
if (dataItem.Cells[2].Text == "My heading that I'd like to show")
{
dataItem["Name"].ColumnSpan = 8;
dataItem["Name"].HorizontalAlign = HorizontalAlign.Center;
dataItem["Name"].BackColor = System.Drawing.Color.Black;
dataItem["Name"].ForeColor = System.Drawing.Color.White;
dataItem["Address"].Visible = false;
dataItem["City"].Visible = false;
dataItem["Province"].Visible = false;
dataItem["Country"].Visible = false;
}
}
} |
That’s what I came up with and it seems to work great. If anyone has a better technique for implementing this, please let me know.
In this post, I’m going to talk a little bit about how to access specific controls within a RadGrid while that grid is in edit mode. There are several reasons you may want to do this:
- You might need to set some defaults for the control.
- You want to perform some calculation and output some default value to the control.
- You may need to change the attributes of a control (color, font etc).
In order to achieve any of the above, we need a way to get access to the controls while in edit mode.
To begin, you’ll need to add the ItemDataBound event to your grid, so that when we’re in edit mode and the items are being bound, we can perform our custom code.
1
| OnItemDataBound="RadGrid1_ItemDataBound" |
Next, add the method to handle the ItemDataBound event for the grid as follows:
1
2
3
4
5
6
7
8
9
| protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
{
if ((e.Item is GridEditableItem) && (e.Item.IsInEditMode))
{
GridEditableItem edititem = (GridEditableItem)e.Item;
TextBox txtbx = (TextBox)edititem["ColumnUniqueName"].Controls[0];
txtbx.Text = "";
}
} |
The above code is pretty straight forward. We check first to see if we’re in edit mode, because we don’t want to be performing this code during any other time. We create a GridEditableItem object so that we can talk to the controls of the item we’re currently editing. And finally, if it’s a textbox we’re dealing with, create a TextBox object and using the unique name you’ve assigned that column, we can access the control within it.
Now that you have a TextBox object, you can access all the properties and methods of that object as you normally would.
If the control in question is a checkbox, it’s not much different:
1
2
3
4
5
| CheckBox cb = (CheckBox)edititem["ColumnUniqueName"].Controls[0];
if (cb.Checked) {
// perform some custom code
} |
The solution for this was not totally obvious to me when reading the RadGrid documentation, so I did a bit of forum searching and found the solution below:
Let’s say you’ve got a RadGrid on your page, and you’ve configured it already to allow for filtering by setting the AllowFilteringByColumn property to true as follows:
1
| <radG:RadGrid ID="rgDistricts" runat="server" PageSize="5" Skin="Default" AllowFilteringByColumn="true" AllowPaging="True" AllowSorting="True" GridLines="None" AutoGenerateColumns="False" OnDeleteCommand="DistrictDelete" OnItemCommand="ItemClick" OnNeedDataSource="District_NeedDataSource"> |
The code above will insert filter boxes and a filter menu into your grid which will allow users to enter a value and select a filter funtion to filter the grid. This works good except it requires that a user enter a value and then use the mouse to select how they want to filter on that value before the grid is affected.
It would be faster and a better user experience to allow users to enter a value and then hit the enter key and then have the grid filter. So to achieve this, you have to tell each of your bound columns that a. you want to auto post back on filter and b. what default filter funtion to use as follows:
1
| <radG:GridBoundColumn DataField="Address" SortExpression="Address" HeaderText="Address" UniqueName="Address" AutoPostBackOnFilter="true" CurrentFilterFunction="Contains"> </radG:GridBoundColumn> |
Let’s say you have an employee table and you want to be able to create a hyperlink on the employee name column with a custom url in the form of: “employee.aspx?ID=”
Within an asp.net datagrid, you could achieve this by creating a hyperlinkcolumn and specifying the DataNavigateUrlField and the DataNavigateUrlFormatString as follows:
1
| <asp:HyperLinkColumn DataNavigateUrlField="EmployeeID" DataNavigateUrlFormatString="employee.aspx?ID={0}" DataTextField="Name"></asp:HyperLinkColumn> |
If you’re using a Telerik TreeView control, however, the syntax is slightly different. While you can specify DataBindings within a Telerik TreeView control, there doesn’t seem to be a NavigateUrlFormatString property available. You can set the NavigateUrl and the NavigateUrlField property, but that’s not enough to get the same results as above.
The best way to accomplish this is:
Within the RadTreeView control, add an OnNodeBound event as follows. This will enable us to set our NavigateUrl at the same time our nodes are being bound to the treeview thus giving us more control:
1
| <radT:RadTreeView ID="rtvEmployees" Skin="Default" runat="server" OnNodeBound="Node_Bound"></radT:RadTreeView> |
Within your code behind file, create a function as follows:
1
2
3
4
| protected void Node_Bound(object sender, Telerik.WebControls.RadTreeNodeEventArgs e)
{
e.NodeBound.NavigateUrl = "employee.aspx?ID=" + e.NodeBound.Value;
} |
Don’t forget that whether you build the structure programmatically or inline, you’ll need to specify the DataFieldID, the DataFieldParentID, the DataTextField and the DataValueField. In my case, I did it programmatically as follows:
1
2
3
4
5
6
7
8
9
10
11
| rtvUserGroups.DataSource = dsTreeView;
rtvUserGroups.DataFieldID = "EmployeeID";
rtvUserGroups.DataFieldParentID = "ParentID";
rtvUserGroups.DataValueField = "EmployeeID";
rtvUserGroups.DataTextField = "Name";
rtvUserGroups.DataBind(); |
The steps below outline how to get started using Telerik Ajax within a SharePoint custom application page. If you’re developing a web part or even just a custom asp.net application, the concepts are still the same.
- Add the RadAjax.Net2.dll file into the GAC. If you need to find the RadAjax.Net2.dll file, if you’ve installed the Telerik web controls to your computer, they should be in the Telerik folder where you installed the Telerik suite.
- Insert the following register tag at the top of the aspx page:
1
| <%@ Register Assembly="RadAjax.Net2, Version=1.8.1.0, Culture=neutral, PublicKeyToken=3f7b438d1c762d0b" Namespace="Telerik.WebControls" TagPrefix="radA" %> |
In order to determine what the version and publickeytoken should be, put the dll into the GAC (c:\windows\assembly) and then right click the dll, click on Properties and you can copy and paste the version and publickeytoken.
- IISRESET
- Now that you have the control registered, it’s time to use it. Within the telerik ajax dll there’s two main controls to be aware of. The ajaxpanel and the ajaxmanager. The example I’ll show below is specific to the ajaxpanel. The following info is directly from the telerik ajax help:
When to use RadAjaxPanel
RadAjaxPanel is a lightweight control that lets you update a part of your web page with AJAX while keeping the rest of the page working with postbacks.
AJAX Panel is more suitable for cases when you need to update a group of neighboring controls at once. You have to wrap the controls that should be ajaxified in the AJAX Panel. Only controls that are inside the Panel will be updated via AJAX. You cannot set the Panel to update external controls on the page.
When a control (inside the Panel) tries to postback, it will make an AJAX request and all controls in the Panel will be updated.
When to use RadAjaxManager
AJAX Manager offers a complete solution for turning a postback-based application into an AJAX-driven one.
RadAjaxManager control is mostly dedicated to complex scenarios. With AJAX Manager you have many AJAX initiator controls that update different non-adjacent controls. This is the major difference with AJAX Panel, which updates only itself (and controls that it holds).
So if you have a button, that does a lookup and populates some fields as an example, all you need to do is wrap that button and those fields inside a panel control. Note that if you just wrap the button within the panel, then the fields are not affected, and so clicking on the button will result in nothing.
Give that a shot, it’s pretty straight forward and easy to do and makes your custom web applications look a whole lot slicker!
If you’re building custom application pages within MOSS and need some guidance on how to build your pages using Telerik controls, I’ve outlined some steps to get you started.
- Create a new folder within the
1
| c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS |
directory to store your custom application pages. For example:
1
| c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\CustomPages |
Download Files
- Create a new aspx page and use the attached code as a starting point. Let’s name it Demo.aspx. The trick to creating this page was to use the td styles defined by SharePoint to accomplish the same look and feel as the rest of the layouts pages within the application. We will see how this works in the next few steps. The attached zip folder contains two files: Demo.aspx and DemoFinal.aspx. The only difference between these two files is that DemoFinal.aspx contains assembly registrations for the telerik controls, and replaces the standard asp:TextBox control with the Telerik RadDatePicker control.
- In order to add breadcrumbs to your new custom application page, you’ll have to add an entry to the layouts.sitemap file located in the inetpub folder
1
| C:\Inetpub\wwwroot\wss\VirtualDirectories\80\_app_bin |
as outlined in Jan’s blog
1
| <siteMapNode title="Demo" url="/_layouts/snc/Demo.aspx"/> |
- The next step is to add a safe control entry for the rad calendar control. One thing to note is that the radcalendar control also utilizes the radinput control, but we only need to add radcalendar.net2.dll as a safe control entry even though both will reside in the gac.
1
| <SafeControl Assembly="RadCalendar.Net2, Version=2.2.1.0, Culture=neutral, PublicKeyToken=a1432cd341173140" Namespace="Telerik.WebControls" TypeName="*" Safe="True" /> |
- Install radcalendar.net2.dll to the gac
- Install radinput.net2.dll to the gac
- If you plan on skinning your control, you have to add the RadControls\Calendar\Skins to the web app root. An example of the web app root would be
1
| c:\Inetpub\wwwroot\wss\VirtualDirectories\80. |
In order to track this down, within IIS manager, right click on the web site properties and click on Home Directory. That should tell you where your website root is located. Copy the files to this location.
The hierarchy should look similar to the screenshot below:

- You can now apply the skin in your control by editing the skin property as follows:
- You can review what your final version should look like by comparing it to the file attached to this post.