Dynamic content is loaded into both panes. The pane on the left has tree controls which can be expanded to vertically lengthen the page and the pane on the right has a data grid with resizable columns which can horizontally lengthen the size of the page.
There is a requirement that there are no scroll bars inside the splitter/panes and that the only content that can be clipped is the horizontal content in the left pane. This means that the height will need to expand as needed in both panes and that the width would expand as needed in the right pane so that all content is visible without scrollbars.
Is it possible to configure the splitter and panes to do this?
Edit:
I noticed using IE Developer Tools and viewing the html that the rad splitter is rendered as a table with the panes as divs inside of cells. The pane divs appear to have an inline height and width that is apparently calculated and set in pixels. If I change these values to 100% in the developer tool, I get the display I am looking for. However, as soon as I move the splitter, they of course reset back to fixed pixels and the scroll bars reappear.
16 Answers, 1 is accepted
Hi James,
I believe you will find the following KB article useful: http://www.telerik.com/support/kb/aspnet-ajax/splitter/initially-resize-the-radsplitter-according-to-its-content.aspx. It explains how to resize the splitter according to its content initially.
You can adopt the same approach and also handle the OnColumnResized event of the RadGrid and the OnClientNodeExpanded event of the RadTreeView to resize the splitter accordingly.
You can also set the RadPanes' Scrolling property to None as well to avoid having scrollbars.
As for your last question - RadSplitter dynamically calculates its dimensions via JavaScript and can only take percentage values as its overall size in respect to its parent element.
I hope this helps you advance in your project.
All the best,
Marin
the Telerik team
Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
The solution you linked to seems to solve the issue for me when the page is refreshed, but not on initial load. For me, when the page first loads, even though the RadGrid inside one of the RadPanes is loaded with, say, 30 rows, the splitter is capped at 400x400 and only the first N rows (e.g., 7) show. The rest of the grid is cut off.
When I refresh the page (F5), the splitter is resized correctly.
There appears to be some sort of timing issue. Can the splitter's OnClientLoaded event handler fire *before* the contents in the splitter (e.g., a RadGrid inside a RadPane) have finished loading? If so, what's the proper way to handle this?
It is possible that the Splitter is initialized before its content if the content is heavy enough. The splitter is merely a container and does not have too much to render, unlike, for example, a Grid with many records.
A possible workaround would be to use the pageLoad() function that is fired when all controls are loaded on the page and resize the Splitter there as well. You could also try setting the Splitter's VisibleDuringInit property to false.
Greetings,
Marin
the Telerik team
Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!
The grid in question is "heavy" relative to the splitter. VisibleDuringInit = "false" won't work while the grid is loading due to cosmetic reasons.
Yeah, I figured out that I should do it in pageLoad, but thanks for validating that.
When the splitter resizes to fit dynamic content, it "sticks" for a second in a partially collapsed state before expanding. That's the last piece of the resizing puzzle. Do you know how to handle that?
Thanks!
I am glad that you found the solution yourself. As for the resizing delay - I am not sure what you mean by partially collapsed state, but I suppose you refer to the small delay between the content/browser resize and the actual resizing of the splitter. This happens because the Splitter has to recalculate all its dimensions on the client and replace the new ones in the markup. This is an operation that simply takes some time to complete and cannot be avoided. If that is not what you mean please explain in some more details the issue you are having and/or send us a video capture and/or screenshots with this behavior.
Kind regards,
Marin
the Telerik team
Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!
Picture a splitter with two panes (left and right and a vertical split bar between them). The left pane contains a tree view and the right pane contains a grid. When the page loads, the left pane immediately appears at about 1/2 the width specified in the left pane's declaration, and the right pane does something similar. Then, a split second later, both panes resize to the specified width.
I'm using the same declared width in the pane markup as well as the pageLoad event handler.
I am not sure I understand you correctly, but I believe that this is either the initial sizing of the splitter (for which I advised the VisibleDuringInit property), or it is also very probable that we are talking about the same delay while the new sizes are being calculated. You can confirm if it is one of these by turning off the property and calling the resizing functionality with a large timeout (for example a few seconds). If you are certain that this is some different issue please send us a simple, runnable project that isolates it so we can examine it locally and see the cause of the issue.
All the best,
Marin
the Telerik team
Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!
I used the approach suggested by Marin and was able to get the panes in the grid to resize automatically as I wanted them to. I ended up needing to handle the following events in javascript for each of the panes:
OnClientResized
OnClientBeforeResize
OnClientExpanded
OnClientCollapsed
OnClientBeforeCollapse
OnClientBeforeExpand
It was rather involved but I was able to get it to work just the way I wanted. I also set the VisibleDuringInit to false because when it is first loaded the panes showed up smaller and then resized after a second or two. I didn't like having all the blank white space on the screen while it was loading so I displayed a loading message that disappeared when panes were displayed. I only had this problem when the page first loaded.
I am trying to do the samething here but keep getting error. I am trying to set the width of a radpane based on a Treeview that is in that pane. I have attached what i have to see if you can see were i am going wrong. Want to set the width of the leftpane based on the treeview in it. anytime a node is expanded.
<%@ Master Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="false" CodeBehind="SideNavigation.master.vb"
Inherits="WebPortal.SideNavigation" %>
<
asp:Content
ID
=
"sidemenu"
ContentPlaceHolderID
=
"sidenavigation"
runat
=
"server"
>
<
script
language
=
"javascript"
type
=
"text/javascript"
>
function HighlightNode(value) {
var tree = $find("<%= RadTreeView1.ClientID %>");
var node = tree.findNodeByValue(value);
if (node != null) {
node.startEdit();
}
}
function SplitterLoaded(splitter, arg) {
var pane = splitter.getPaneById('<%= LeftPane.ClientID %>');
var width = pane.getContentElement().scrollwidth;
splitter.set_width(width);
pane.set_width(width);
}
</
script
>
<
div
id
=
"ParentDivElement"
style
=
"height: 100%; padding-top: 15px; background-color: #465157;"
>
<
telerik:RadAjaxManager
ID
=
"RadAjaxManager1"
runat
=
"server"
>
</
telerik:RadAjaxManager
>
<
telerik:RadSplitter
ID
=
"MainSplitter"
runat
=
"server"
Height
=
"100%"
Width
=
"100%"
Orientation
=
"Horizontal"
VisibleDuringInit
=
"false"
>
<
telerik:RadPane
ID
=
"MainPane"
runat
=
"server"
Scrolling
=
"none"
MinWidth
=
"500"
>
<
telerik:RadSplitter
ID
=
"NestedSplitter"
runat
=
"server"
Skin
=
"Outlook"
LiveResize
=
"true"
>
<
telerik:RadPane
ID
=
"LeftPane"
runat
=
"server"
MinWidth
=
"255"
MaxWidth
=
"400"
>
<!-- Place the content of the pane here -->
<
div
class
=
"sidebar"
>
<
div
class
=
"sbcorner sbTL"
>
</
div
>
<
div
class
=
"sbcorner sbTR"
>
</
div
>
<
div
class
=
"sbcorner sbBL"
>
</
div
>
<
div
class
=
"sbcorner sbBR"
>
</
div
>
<
div
class
=
"sbmaincontents"
>
<
h1
class
=
"title2"
>
Reporting</
h1
>
<
telerik:RadTreeView
ID
=
"RadTreeView1"
runat
=
"server"
Skin
=
"WebBlue"
OnClientNodeExpanded
=
"SplitterLoaded"
>
<
DataBindings
>
<
telerik:RadTreeNodeBinding
Expanded
=
"True"
/>
</
DataBindings
>
</
telerik:RadTreeView
>
</
div
>
</
div
>
</
telerik:RadPane
>
<
telerik:RadSplitBar
ID
=
"VerticalSplitBar"
runat
=
"server"
CollapseMode
=
"Forward"
/>
<
telerik:RadPane
ID
=
"ContentPane"
runat
=
"server"
>
<!-- Place the content of the pane here -->
<
div
class
=
"main"
>
<
div
class
=
"corner TL"
>
</
div
>
<
div
class
=
"corner TR"
>
</
div
>
<
div
class
=
"corner BL"
>
</
div
>
<
div
class
=
"corner BR"
>
</
div
>
<
div
class
=
"maincontents"
>
<
asp:ContentPlaceHolder
ID
=
"MainContent"
runat
=
"server"
/>
</
div
>
</
div
>
<
telerik:RadNotification
ID
=
"RadNotification1"
runat
=
"server"
Animation
=
"Fade"
Position
=
"BottomRight"
AutoCloseDelay
=
"10000"
Width
=
"300"
TitleIcon
=
"warning"
ContentIcon
=
"warning"
>
</
telerik:RadNotification
>
</
telerik:RadPane
>
</
telerik:RadSplitter
>
</
telerik:RadPane
>
</
telerik:RadSplitter
>
</
div
>
</
asp:Content
>
The issue here is that the sender of the function is not a RadSplitter, but a RadTreeView, thus the following line will cause an error, since the RadTreeView does not have the methods used:
var
pane = splitter.getPaneById(
'<%= LeftPane.ClientID %>'
);
What I can suggest is that you use the $find() method to get a reference to the splitter first:
function
SplitterLoaded()
{
var
splitter = $find(
"<%=NestedSplitter.ClientID %>"
);
var
pane = splitter.getPaneById(
'<%= LeftPane.ClientID %>'
);
.....
}
Kind regards,
Marin
the Telerik team
Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!
I see that in your previous post you have a splitter with Horizontal Orientation, which means that you need to use a different function to resize it. The error you get comes from the fact that you are trying to get the width of an object that does not have an explicit width (the horizontal pane). Please examine closely the following KB article to see the difference between a Horizontal and Vertical splitter: http://www.telerik.com/support/kb/aspnet-ajax/splitter/initially-resize-the-radsplitter-according-to-its-content.aspx.
For your convenience I prepared a simple page that will resize a horizontal splitter when a treeview is expanded and collapsed. You can find it attached and here is a video with the expected behavior: http://screencast.com/t/2YKbkcOR. Please note my comments in the code and use this as a basis for your further development.
Best wishes,
Marin
the Telerik team
Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!
function resizeSplitter()
{
setTimeout(function ()
{
var treeView = $find("<%=RadTreeView1.ClientID %>");
//gets a correct referece to the TreeView since it is not always the sender
var splitter = $find("<%=RadSplitter1.ClientID %>");
//get a correct reference to the Splitter, since the sender is not the Splitter, but the TreeView
var pane = splitter.getPaneById('<%= RadPane1.ClientID %>');
var bounds = $telerik.getBounds(treeView.get_element()); //this gets the actual size of the TreeView, even when it collapses
//as otherwise the height of the Radpane would remain too large, since it is already set
//this resizes the splitter, as shown in the KB article
pane.set_width(bounds.width);
splitter.set_width(bounds.width);
}, 400);
//some timeout to allow for the animation
}
Well after some more testing i seam to have found issue. For some reason the getbounds method for the treeview is always returning the width from the pane and not the width of the treeview. If i look at the height at when expanding it does indeed change like expected but not the vaule for the width. Is this a bug in the treeview control or am i still doing something incorrect here. Again thanks for the time.
This issue is part of the reason why my demo changes the height. The RadTreeView renders as a div element and thus its width is 100% of it parent's width. This means that it is expected that the getBounds method will return the width of the pane when asked for the width of the RadTreeView, since they are the same.
What I can suggest at this point to provide some usability is that you set a certain size for the pane that will contain the RadTreeView and in the OnClientNodeExpanded event scroll the last node into view, for example like this:
function
OnClientNodeExpanded(sender, args)
{
var
nodes = args.get_node().get_nodes();
var
lastNode = nodes.getItem(nodes.get_count()-1);
lastNode.scrollIntoView();
}
http://www.telerik.com/help/aspnet-ajax/treeview-client-objects-radtreenode.html
http://www.telerik.com/help/aspnet-ajax/treeview-client-objects-radtreeview.html
An alternative solution is giving all the RadTreeView explicit dimensions so as to make sure it will not overflow the RadPane.
By using the API and a lot of DOM traversal perhaps it is possible that you access all the child nodes' span elements that contain the text, then get the x offset and width for each of them (again via the getBounds() method) and copmare them, thus finding the one that extends farthest to the right, which will enable you to get the actual width of the RadTreeView. I cannot guarantee that this approach will work and that it will be trouble-free or easy to impelement, it is simply an idea. I hope you will be able to get this customized functionality working.
Best wishes,
Marin
the Telerik team
Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!
Main thing is to be able to set the width of the pane to length of the longest tree node.
The attached code does this during the data binding of the node.
Its some code i found and use for sizing the combobox dropdown to fit longest strings.
Again tahnks for the time and help.
Protected Sub RadTreeView_OnNodeDataBound(ByVal sender As Object, ByVal e As RadTreeNodeEventArgs) Handles RadTreeView1.NodeDataBound
Dim tree As RadTreeView = DirectCast(sender, RadTreeView)
'set the width of the expanded tree nodes to the width of the longest string in the node collection
Dim MaxWidth As Integer = 150
For Each item As RadTreeNode In tree.GetAllNodes()
Dim Width As Integer = TextWidth(item.Text)
If Width > MaxWidth Then
MaxWidth = Width
End If
Next
LeftPane.Width = New Unit(MaxWidth)
End Sub
Private Function TextWidth(ByVal TheText As [String]) As Integer
'function used to measure the width needed to display a string value then control can be set to this width
Dim DrawFont As Font = Nothing
Dim DrawGraphics As Graphics = Nothing
Dim TextBitmap As Bitmap = Nothing
Try
TextBitmap = New Bitmap(1, 1)
DrawGraphics = Graphics.FromImage(TextBitmap)
DrawFont = New Font("Segoe UI", 12)
Dim Width As Integer = CInt(DrawGraphics.MeasureString(TheText, DrawFont).Width)
Return Width
Finally
TextBitmap.Dispose()
DrawFont.Dispose()
DrawGraphics.Dispose()
End Try
End Function