This is a migrated thread and some comments may be shown as answers.

Calculating pane dimensions properly

1 Answer 68 Views
Splitter
This is a migrated thread and some comments may be shown as answers.
Sean
Top achievements
Rank 2
Sean asked on 05 Jul 2011, 11:03 PM
Hi all,

I am currently attempting to solve a small bug in my web project. The bug is that, in certain scenarios, the width is too large of a RadPane I have created programatically. 

So, first off, the code that is causing the issue:

/// <summary>
/// Creates a RadSplitter and places the two panes it will hold onto it.
/// In addition, sets those panes dimensions such that they are appropriate for
/// the orientation of the RadSplitter.
///
/// I divide height and width in half because there are two panes.
/// </summary>
/// <returns> The rad splitter. </returns>
public static CormantRadSplitter CreateNewContent(Orientation orientation, RadPane parent)
{
    Logger.InfoFormat("Creating new content to be placed upon: {0}", parent.ID);
 
    CormantRadSplitter splitter = new CormantRadSplitter(orientation);
 
    CormantRadPane firstPane = new CormantRadPane();
    CormantRadDockZone firstDockZone = new CormantRadDockZone();
    firstPane.Controls.Add(firstDockZone);
    splitter.Controls.Add(firstPane);
 
    CormantRadPane secondPane = new CormantRadPane();
    splitter.Controls.Add(new CormantRadSplitBar(orientation, firstPane.ID, secondPane.ID));
 
    CormantRadDockZone secondDockZone = new CormantRadDockZone();
    secondPane.Controls.Add(secondDockZone);
    splitter.Controls.Add(secondPane);
 
    switch (orientation)
    {
        case Orientation.Horizontal:
            firstPane.PanePosition = PanePositions.Top;
            secondPane.PanePosition = PanePositions.Bottom;
            //firstPane.Height = secondPane.Height = new Unit(parent.Height.Value / 2, UnitType.Pixel);
            //firstPane.Width = secondPane.Width = parent.Width;
            break;
        case Orientation.Vertical:
            firstPane.PanePosition = PanePositions.Left;
            secondPane.PanePosition = PanePositions.Right;
            //firstPane.Height = secondPane.Height = parent.Height;
            //firstPane.Width = secondPane.Width = new Unit(parent.Width.Value / 2, UnitType.Pixel);
            break;
    }
 
    return splitter;
}

The lines which are commented out are the culprits.

I believe the issue arises from 'fighting' with what Telerik/WebControls is trying to do. These panes are created with the intent of filling all the space they are given, but no more. The panes will do that by default -- their height and width properties are unset -- which causes them to use height/width: auto.

So, why do I have code which sets their height and width, then? My reasoning is that it is impossible to properly save the state of my page without explicitly defining the dimensions. If I execute the above code, with lines commented out, and then perform a hard refresh on the page -- the controls expect dimensions to regenerate with. If I leave them unset here, they will indeed figure out how to adjust themselves (they figure it out even if I DO tell them dimensions!) Unfortunately, the panes are resizable by the end user. If I do not save/load the dimensions of each pane then it is impossible to support persisting resized panes. (Not saving dimensions will cause each pane to take up half of its parents space assuming 2 panes regardless of how they were sized before refresh).

So, I am trying to setup each panes dimensions properly. I thought the above code did just that, but I am experiencing a little quirk! If I place a RadSplitter with vertical orientation on the page, then place a RadDock in the RHS pane, the RadDock spills out of the RadPane.

Here's an example image: http://i.imgur.com/4T8tu.png

In this image you will see a few things: An example where the RadDock is spilling out of the pane on the RHS, as well as an example where the RadDock stays contained inside of a horizontal-oriented splitter's pane. I am not sure why the horizontal one always seems to be fine.

Nevertheless, the issue seems to be pretty easy to see -- I just want to make the right decision. When I create that vertical splitter seen in the image -- the width of each pane (for example) is 502px. After a hard refresh and inspecting the pane elements on the page, I see that their widths have been changed to 499 and 500. These post-hardrefresh widths are appropriate, my calculated widths are not. 

Is this just as simple as taking into account the width of the RadSplitBar being put onto the RadSplitter -- and subtracting that from the widths of each of the panes? If so, I wonder why the same issue does not occur with horizontal-oriented splitters? Also, the width of a splitBar isn't known at creation -- so I'd just be using a hardcoded width here.. a little scary.

Anyway, like I said.. I could probably force this solution pretty easily. I am just trying to understand -why- this is happening and what I can do to fix it properly in a way that's understandable to future developers -- not just a hardcoded number.

Thanks for your time

Sean


1 Answer, 1 is accepted

Sort by
0
Accepted
Dobromir
Telerik team
answered on 11 Jul 2011, 10:15 AM
Hi Sean,

Your assumption is correct, when sizing the panes you need to take into account the size of the splitbar as well. In the provided code snippet each pane is sized according to the parent pane, thus the splitbar is not included, and after that I believe the dockzone nested inside the pane is sized according to the size of the pane.

What is happening is that on the initial load(with the incorrect sized panes) the panes are not sized correctly and they exceed the parent splitter's size, after the postback the splitter automatically calculates the size of its panes and includes the size of the splitbar.

To avoid this issue you will need to take into account the size of the splitbar when calculating the size of the panes - the default size of the splitbar is 4px. I would suggest you to use a static variable defining the size of the splitbar for easier future modifications.

switch (orientation)
{
    case Orientation.Horizontal:
        firstPane.PanePosition = PanePositions.Top;
        secondPane.PanePosition = PanePositions.Bottom;
        firstPane.Height = secondPane.Height = new Unit((parent.Height.Value - SplitBarSize) / 2, UnitType.Pixel);
        firstPane.Width = secondPane.Width = parent.Width;
        break;
    case Orientation.Vertical:
        firstPane.PanePosition = PanePositions.Left;
        secondPane.PanePosition = PanePositions.Right;
        firstPane.Height = secondPane.Height = parent.Height;
        firstPane.Width = secondPane.Width = new Unit((parent.Width.Value - SplitBarSize) / 2, UnitType.Pixel);
        break;
}


Kind regards,
Dobromir
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!

Tags
Splitter
Asked by
Sean
Top achievements
Rank 2
Answers by
Dobromir
Telerik team
Share this question
or