WrapPanel Embedded in a ScrollViewer RRS feed

  • Question

  • Say I have two objects in a WrapPanel, and I have it in a Scrollviewer.

    What I want; One object to move beneath the other when the window is re-sized smaller than will allow both objects in the viewport of the WrapPanel, and the Horizontal Scrollbar on the ScrollBar to invoke when the windows resized further.

    What I get; If I have HorizontalScrollbarVisibility set to Auto, the WrapPanel is ignored and it just puts up the Horizontal Scrollbar. If I set it to Disabled, then it respects the WrapPanel but I get no HorizontalScrollBar after one object has moved beneath the other from it.

    So like an example of what I have







    Anyone have an idea how to accomplish? Can I bind to a ViewportWidth or an ActualWidth somewhere? I've tried various ways but no luck exactly. Thanks for taking the time to share some insight if you can. :)

    Please mark answers as helpful when used, and answered when completed.

    Friday, March 9, 2012 5:11 AM

All replies

  • I've tried to get this working several times over the years with widgets and have found that it can't be done with an all-xaml solution. Then I tried switching the visibility of the scrollbar once the area shrank below a set size, and it changed the stackpanel into a single horizontal line.

    The best solution I've found so far is to fake it: at most sizes, the horizontal scrollbar is disabled and the stackpanel orientation is horizontal. Once it collapses below a fixed size, switch the horizontal scrollbar on, disable the vertical scrollbar, and change the stackpanel orientation to vertical. Annoying and requires more c# than I'm normally comfortable with, but it works.

    Leon Terry
    Blog | TFK Labs | Twitter

    • Proposed as answer by VLTII Thursday, March 15, 2012 6:18 PM
    Thursday, March 15, 2012 6:18 PM
  • What I ended up doing for now was since I have minwidth set for the entire app, I basically bound the height of the object 2 to the height of object 1 (since object one will change values based on data when you load it) and have a vertical scrollviewer around object two. Then I bound the maxwidth of object two to the width of object 1 and set a minwidth on it. So basically what happens is the screen loads, if there's X amount of space available next to object 1, then object two stays on its right and spans the height (which fills the page quite nicely I might add)

    Then on resize the wrappanel invokes and kicks object two underneath it but will remain the same size until the object is updated (in this case its a notes screen) so when its updated it then spans the full width under object 1 and fills the screen perfectly. The idea was I have to deal with users in multiple resolutions but have to be efficient with my use of real estate on the screen.

    So... If a user loads the app and has enough room to put them side by side, then it loads that way and looks great! However if the user has a lower resolution size then it loads underneath object 1 and also looks great! I was going to try and tinker with some trigger settings for Layout Changes to see if I couldnt make it a bit more robust and set sizes that way but didnt have time before it needed delivered but will come back to it I'm sure. I wanted to accomplish this in pure xaml, and came pretty darn close and either way ended up with a fine solution. Thanks for sharing the insight! Hopefully I get a chance to tinker more later and try out these ideas. Cheers :)

    ps- Hope the explanation made some sense, can post some source later if ya like.

    Please mark answers as helpful when used, and answered when completed.

    Thursday, March 15, 2012 7:16 PM
  • Yeah actually, I would. The widget I was working on was part of a dashboard using a dockmanager so I'm not sure if that solution will work for me, but I'd still like to take a peek :)

    Leon Terry
    Blog | TFK Labs | Twitter

    Monday, March 19, 2012 6:43 PM
  • <StackPanel x:Name="StackPanel_Container">
        	  <ei:FluidMoveBehavior AppliesTo="Children">
        	      <QuadraticEase EasingMode="EaseInOut"/>
        	      <QuadraticEase EasingMode="EaseInOut"/>
       <StackPanel x:Name="StackPanel_Form" Width="560">
          <!-- Tons of irrelevant stuff 
               contained here as Object 1 -->
       <Grid x:Name="Grid_SideNotes" 
          Height="{Binding ElementName=StackPanel_Form, Path=ActualHeight}" 
          MaxWidth="{Binding ElementName=StackPanel_Form, Path=ActualWidth}"
          HorizontalAlignment="Stretch" Margin="0,0,0,10"/>
            <!-- Tons of irrelevant stuff 
               contained here as Object 2 -->
            <!-- More irrelevant stuff to
                 always be displayed under Objects 1 & 2

    Keep in mind it was an Adhoc fix for my particular situation but came out quite nicely. Also I do have the entire App set to a MinWidth of I think like 800. So it renders correct based on how it's loaded the first time, it won't self correct unless say someone adds enough text to fill the maxwidth of object 2 when its below Object 1, then it will retain that width and line up with the elements above it, if that makes sense. Hope it helps, if you have questions we can exchange email addy's and I can show you more. Cheers :)

    ps- Forgot to add I'm dropping this stuff in dynamically via Caliburn Micro so all this is nested in the ScrollViewer instead of vice versa in case you were wondering where it was.It's a large enterprise app, hard to just paste the bits of how my circumstance works together so hope its understandable.

    Please mark answers as helpful when used, and answered when completed.

    Monday, March 19, 2012 8:57 PM