Skip to main content
Home Forums Silverlight Programming Programming with .NET - General Is there a way of easily create a dockpanel taking as base a stackpanel? Just to have the last child fill option
13 replies. Latest Post by sinosoidal on March 26, 2008.
(0)
sinosoidal
Member
664 points
373 Posts
03-22-2008 9:56 PM |
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
swildermuth
Star
8320 points
1,546 Posts
03-23-2008 10:03 AM |
Do a Google Search. There was an example at MIX of building a DockPanel that was very straightforward.
03-23-2008 10:12 AM |
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"
Jabb
462 points
81 Posts
03-23-2008 12:09 PM |
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
03-23-2008 4:18 PM |
I need to try it out. Thx
03-23-2008 7:02 PM |
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?
03-23-2008 8:08 PM |
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.
03-24-2008 3:36 AM |
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.
This ist the way i'm importing:
xmlns:jabb="clr-namespace:Jabb.Controls;assembly=Jabb.dll"
03-24-2008 4:07 AM |
It was not working because i was putting .dll at the end.
It is working now.
Thx a lot,
03-24-2008 4:48 AM |
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
03-24-2008 11:38 AM |
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?
03-25-2008 5:46 PM |
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 = Children; 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;}
03-25-2008 6:24 PM |
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,
03-26-2008 7:17 AM |
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:
{
child.Measure(
totalDesiredHeight -= lastLeftRightHeight;
totalDesiredHeight += child.DesiredSize.Height;
lastLeftRightHeight = child.DesiredSize.Height;
}
totalDesiredWidth += child.DesiredSize.Width;
totalDesiredWidth -= lastTopBottomWidth;
lastTopBottomWidth = child.DesiredSize.Width;
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,