Page view counter
Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option
Last post 03-26-2008 7:17 AM by sinosoidal. 13 replies.
Sort Posts:
03-22-2008 9:56 PM
Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Hi,

 I really love the last child fill option of the dockpanel is very usefull. I can think of the stackpanel where the last element is grown until the end of the parent container. I just want to have the opinion of more skilled people in order to have this implementation as easy as possible.

Any tips?

Thx,

Nuno 

--

Imagining (and touching) the future
http://www.nunosantos.net/
http://www.myspace.com/sinosoidal

sinosoidal

Loading...
Joined on 01-07-2008
Braga, Portugal
Posts 373
03-23-2008 10:03 AM
Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Do a Google Search.  There was an example at MIX of building a DockPanel that was very straightforward.

(If this has answered your question, "Mark as Answer")

Shawn Wildermuth
C# MVP, MCSD, Speaker and Author

Silverlight 2 Workshop
November 19-21, 2008 - Seattle, WA
December 1-3, 2008 - Dallas, TX
http://silverlight-tour.com

swildermuth

Loading...
Joined on 10-13-2003
Atlanta, GA
Posts 1,246
03-23-2008 10:12 AM
Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Hi,

 My search keywords didnt provide any decent result. Can you give me some ideas here?

I was searching by "dock panel silverlight 2 how to"

 Thx,

Nuno

--

Imagining (and touching) the future
http://www.nunosantos.net/
http://www.myspace.com/sinosoidal

sinosoidal

Loading...
Joined on 01-07-2008
Braga, Portugal
Posts 373
03-23-2008 12:09 PM
Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

I've uploaded my version of the DockPanel at

http://home.comcast.net/~jabbaloo/DockPanel.zip

The biggest weird thing I ran into when trying to put this sample app together is that the DockPanel has to reside in a Silverlight Class Library separate from the main Silverlight Application - if I put the DockPanel.cs code into the main app then the DockPanel.Dock attached property is not recognized. I didn't experience this in my original project because all my custom controls are their own class library.

Anyhoots, hope this helps.

- Jabb
 

Jabb

Loading...
Joined on 03-06-2008
Posts 73
03-23-2008 4:18 PM
Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Hi,

 I need to try it out. Thx

Nuno

--

Imagining (and touching) the future
http://www.nunosantos.net/
http://www.myspace.com/sinosoidal

sinosoidal

Loading...
Joined on 01-07-2008
Braga, Portugal
Posts 373
03-23-2008 7:02 PM
Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Hi Jabb,

 Thx for showing me your solution. I think i'm running into the same problem here. In blend it works perfectly using the xmlns:prefix:_name:clr-namespace..  notation.

 However, when testing the solution it crashes.

 You said you hadn't any problem because your your controls had their own class library. Can you explain that better?

Thx,

Nuno

--

Imagining (and touching) the future
http://www.nunosantos.net/
http://www.myspace.com/sinosoidal

sinosoidal

Loading...
Joined on 01-07-2008
Braga, Portugal
Posts 373
03-23-2008 8:08 PM
Re: Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Make sure that you have something like

xmlns:jabb="clr-namespace:SampleApp;assembly=SampleApp"

instead of 

xmlns:jabb="clr-namespace:SampleApp"

In other words, make sure the assembly is specified - that's why it wasn't working before for me, I didn't have the assembly specified. 

Jabb

Loading...
Joined on 03-06-2008
Posts 73
03-24-2008 3:36 AM
Re: Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

 Hi,

I'm not having success in using your code in my testing application.

My first approach was to include the source code on the project, but now i am trying to reference directly your dll. In both cases i forced the import of the dll.

Doesnt work. Gives an exception on the initialize.

Any tips? 

This ist the way i'm importing:

xmlns:jabb="clr-namespace:Jabb.Controls;assembly=Jabb.dll"

Thx,

Nuno 

 

 

--

Imagining (and touching) the future
http://www.nunosantos.net/
http://www.myspace.com/sinosoidal

sinosoidal

Loading...
Joined on 01-07-2008
Braga, Portugal
Posts 373
03-24-2008 4:07 AM
Re: Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Hi,

It was not working because i was putting .dll at the end.

It is working now.

Thx a lot,

Nuno 

--

Imagining (and touching) the future
http://www.nunosantos.net/
http://www.myspace.com/sinosoidal

sinosoidal

Loading...
Joined on 01-07-2008
Braga, Portugal
Posts 373
03-24-2008 4:48 AM
Re: Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Hi,

Your DockPanel seems not to be imposing itself. At least i'm having a strange behaviour from when i use a dock panel inside another:

Imagine this situation:

<UserControl>
  <src:DockPanel LastChildFill="True">
   <src:DockPanel src:DockPanel.Dock="Left" LastChildFill="True" HorizontalAlignment="Center" VerticalAlignment="Stretch">
    <TextBlock src:DockPanel.Dock="Top" Text="ola" HorizontalAlignment="Left" VerticalAlignment="Top" />
   </src:DockPanel>
   <Image src:DockPanel.Dock="Right" Height="Auto" Width="Auto" MinHeight="500" Source="Resources/entrada.jpg" Stretch="UniformToFill" MaxHeight="500" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
  </src:DockPanel>
</UserControl>

 In this case i was expecting that the textblock could be visible and the image would ocuppie the remaining space, however, the image is using all the space and the textblock is completly smashed and there is no room to it.

Do you know this problem?

Does this happens to you?

Thx

Nuno

 

 

--

Imagining (and touching) the future
http://www.nunosantos.net/
http://www.myspace.com/sinosoidal

sinosoidal

Loading...
Joined on 01-07-2008
Braga, Portugal
Posts 373
03-24-2008 11:38 AM
Re: Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Hi again,

I've been playing with your DockPanel but i think its not 100% functional.

 It works fine for Dock=Top and Dock=Bottom but it is not working for the cases in which is needed one element in Left and another in Right and another in bottom for example.

I would love to put this class working but i havent completly understand the mechanism of the dock panel and of the measure and arrange override methods.

As i have been reading, measure asks all the children its size, but what is it supposed to return?

And about the arranje? Who tells arranje method the availableSize?

Thx,

Nuno

--

Imagining (and touching) the future
http://www.nunosantos.net/
http://www.myspace.com/sinosoidal

sinosoidal

Loading...
Joined on 01-07-2008
Braga, Portugal
Posts 373
03-25-2008 5:46 PM
Re: Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Hi Nuno,

Sorry I haven't replied, I've been really busy with work the past couple of days.

I've fixed the code and will post here since I don't have time to upload to my site. I'll do that later.

Below are the MeasureOverride and ArrangeOverride methods that have been fixed. I'll try to answer the rest of your questions later.

- jabb

 


protected override Size MeasureOverride(Size availableSize)
{
    if (double.IsInfinity(availableSize.Width) || double.IsInfinity(availableSize.Height))
    {
        availableSize = new Size(0, 0);

        foreach (UIElement child in Children)
            child.Measure(availableSize);

        return availableSize;
    }

    double width = availableSize.Width;
    double height = availableSize.Height;

    foreach (UIElement child in Children)
        if (child.Visibility == Visibility.Visible)
        {
            child.Measure(new Size(width, height));

            switch ((Dock)child.GetValue(DockProperty))
            {
                case Dock.Left:
                case Dock.Right:
                    width = Math.Max(width - child.DesiredSize.Width, 0);
                    break;

                case Dock.Top:
                case Dock.Bottom:
                    height = Math.Max(height - child.DesiredSize.Height, 0);
                    break;
            }
        }

    return new Size(
        Math.Max(0, availableSize.Width - width),
        Math.Max(0, availableSize.Height - height)
        );
}

protected override Size ArrangeOverride(Size finalSize)
{
    double left = 0;
    double top = 0;
    double width = finalSize.Width;
    double height = finalSize.Height;

    UIElement child;

    for (int i = 0; i < Children.Count; i++)
    {
        child = ChildrenIdea;

        if (child.Visibility == Visibility.Visible)
        {
            if (lastChildFill && i == Children.Count - 1)
                child.Arrange(new Rect(left, top, Math.Max(0, width - left), Math.Max(0, height - top)));
            else
                switch ((Dock)child.GetValue(DockProperty))
                {
                    case Dock.Left:
                        child.Arrange(new Rect(left, top, child.DesiredSize.Width, Math.Max(0, height - top)));
                        left += child.DesiredSize.Width;
                        break;

                    case Dock.Top:
                        child.Arrange(new Rect(left, top, Math.Max(0, width - left), child.DesiredSize.Height));
                        top += child.DesiredSize.Height;
                        break;

                    case Dock.Right:
                        width -= child.DesiredSize.Width;
                        child.Arrange(new Rect(Math.Max(0, width), top, child.DesiredSize.Width, Math.Max(0, height - top)));
                        break;

                    case Dock.Bottom:
                        height -= child.DesiredSize.Height;
                        child.Arrange(new Rect(left, Math.Max(0, height), Math.Max(0, width - left), child.DesiredSize.Height));
                        break;
                }
        }
    }

    return finalSize;
}
 

Jabb

Loading...
Joined on 03-06-2008
Posts 73
03-25-2008 6:24 PM
Re: Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Hi Jabb,

I have tried it and the arranjment of the Dock seems to be working now. However, i think there are still problems in the HorizontalAligment and VerticalAlgiment of the dock panel. Those options don't work. I would love to finish this dock panel but stil didnt get how things work very well.

Thx for all your help.

Best regards, 

Nuno

--

Imagining (and touching) the future
http://www.nunosantos.net/
http://www.myspace.com/sinosoidal

sinosoidal

Loading...
Joined on 01-07-2008
Braga, Portugal
Posts 373
03-26-2008 7:17 AM
Marked as Answer
Re: Re: Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option

Hi,

I have been playing with the DockPanel dock and i think i have made some important changes that seem to make the panel work almost perfectly:

protected override Size MeasureOverride(Size availableSize)

{

double width = availableSize.Width;

double height = availableSize.Height;

double totalDesiredWidth = 0;

double totalDesiredHeight = 0;

double lastLeftRightHeight = 0;

double lastTopBottomWidth = 0;foreach (UIElement child in Children)

{

if (child.Visibility != Visibility.Collapsed)

{

child.Measure(new Size(width, height));

switch ((Dock)child.GetValue(DockProperty))

{

case Dock.Left:

case Dock.Right:

if (lastLeftRightHeight < child.DesiredSize.Height)

{

totalDesiredHeight -= lastLeftRightHeight;

totalDesiredHeight += child.DesiredSize.Height;

lastLeftRightHeight = child.DesiredSize.Height;

}

totalDesiredWidth += child.DesiredSize.Width;

break;

case Dock.Top:

case Dock.Bottom:if (lastTopBottomWidth < child.DesiredSize.Width)

{

totalDesiredWidth -= lastTopBottomWidth;

totalDesiredWidth += child.DesiredSize.Width;

lastTopBottomWidth = child.DesiredSize.Width;

}

totalDesiredHeight += child.DesiredSize.Height;

break;

}

}

}

Size result = new Size(Math.Min(availableSize.Width, totalDesiredWidth), Math.Min(availableSize.Height, totalDesiredHeight));

return result;

 

I have been developing always with an original dockpanel to compare and the only case that seems not to be working perfectly is lastchildfill in a complex situation

 Check it out,

Best regards,

Nuno

--

Imagining (and touching) the future
http://www.nunosantos.net/
http://www.myspace.com/sinosoidal

sinosoidal

Loading...
Joined on 01-07-2008
Braga, Portugal
Posts 373
Microsoft Communities