Note that there are some explanatory texts on larger screens.

plurals
  1. POWPF WrapPanel with some items having a height of *
    text
    copied!<h2>How do I make a WrapPanel with some items having a Height of *?</h2> <p>A deceptively simple question that I have been trying to solve. I want a control (or some XAML layout magickry) that behaves similar to a Grid that has some rows with a Height of *, but supports wrapping of columns. Hell; call it a WrapGrid. :)</p> <p>Here's a mockup to visualize this. Imagine a grid defined as such:</p> <pre><code>&lt;Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="400"&gt; &lt;Grid&gt; &lt;Grid.ColumnDefinitions&gt; &lt;ColumnDefinition Width="*"/&gt; &lt;/Grid.ColumnDefinitions&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition Height="Auto"/&gt; &lt;RowDefinition Height="*"/&gt; &lt;RowDefinition Height="Auto"/&gt; &lt;RowDefinition Height="*"/&gt; &lt;RowDefinition Height="Auto"/&gt; &lt;RowDefinition Height="Auto"/&gt; &lt;/Grid.RowDefinitions&gt; &lt;Button Grid.Row="0" MinHeight="30"&gt;I'm auto-sized.&lt;/Button&gt; &lt;Button Grid.Row="1" MinHeight="90"&gt;I'm star-sized.&lt;/Button&gt; &lt;Button Grid.Row="2" MinHeight="30"&gt;I'm auto-sized.&lt;/Button&gt; &lt;Button Grid.Row="3" MinHeight="90"&gt;I'm star-sized, too!&lt;/Button&gt; &lt;Button Grid.Row="4" MinHeight="30"&gt;I'm auto-sized.&lt;/Button&gt; &lt;Button Grid.Row="5" MinHeight="30"&gt;I'm auto-sized.&lt;/Button&gt; &lt;/Grid&gt; &lt;/Window&gt; </code></pre> <p><img src="https://i.stack.imgur.com/MI9MT.png"></p> <p>What I want this panel to do is <strong>wrap an item into an additional column when the item can not get any smaller than its minHeight.</strong> Here is a horrible MSPaint of some mockups I made detailing this process. </p> <p><img src="https://i.stack.imgur.com/vBZbL.png"></p> <p>Recall from the XAML that the auto-sized buttons have minHeights of 30, and the star-sized buttons have minHeights of 90. </p> <p>This mockup is just two grids side by side and I manually moved buttons around in the designer. Conceivably, this could be done programmatically and serve as a sort of convoluted solution to this. </p> <p><strong>How can this be done?</strong> I will accept any solution whether it's through xaml or has some code-behind (though I would prefer pure XAML if possible since xaml code behind is tougher to implement in IronPython).</p> <p><em>Updated with a bounty</em></p> <hr> <h1> Meleak's Solution </h1> <p>I managed to work out how to use Meleak's solution in my IPy app: </p> <p>1) I compiled <code>WrapGridPanel.cs</code> into a DLL with <code>csc</code>:</p> <pre><code>C:\Projects\WrapGridTest\WrapGridTest&gt;csc /target:library "WrapGridPanel.cs" /optimize /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\PresentationFramework.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\PresentationCore.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\WindowsBase.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Xaml.dll" </code></pre> <p><strong>Update:</strong> Added the <code>/optimize</code> switch, this nets a small performance increase</p> <p>2) I added it to my application's xaml with the following line.</p> <pre><code>xmlns:local="clr-namespace:WrapGridTest;assembly=WrapGridPanel.dll" </code></pre> <p>This runs fine, but it breaks the designer. I can't really find a workaround for this yet, it looks to be a bug in VS2010. So as a workaround, in order to be able to use the designer, I just add the WrapGridPanel programmatically at runtime:</p> <pre><code>clr.AddReference("WrapGridPanel.dll") from WrapGridTest import WrapGridPanel wgp = WrapGridPanel() </code></pre> <p><strong>Slow performance when resizing</strong>:</p> <p>In my IronPython application, resizing the window containing this WrapGridPanel is slow and hitchy. Could the <code>RecalcMatrix()</code> algorithm be optimized? Could it perhaps be called less frequently? Maybe overriding <code>MeasureOverride</code> and <code>ArrangeOverride</code>, as Nicholas suggested, would perform better? </p> <p><strong>Update</strong>: According to the VS2010 Instrumentation Profiler, 97% of the time spent in RecalcMatrix() is spent on Clear() and Add(). Modifying each element in-place would be a huge performance improvement. I'm taking a whack at it myself but it's always tough modifying someone else's code... <a href="https://i.stack.imgur.com/tMTWU.png" rel="nofollow noreferrer">http://i.stack.imgur.com/tMTWU.png</a></p> <h2>Update: Performance issues have been mostly ironed out. Thanks Meleak!</h2> <p>Here is a mockup of part of my actual application's UI, in XAML, if you wish to try it out. <a href="http://pastebin.com/2EWY8NS0" rel="nofollow noreferrer">http://pastebin.com/2EWY8NS0</a></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload