Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Update</strong><br> Optimized <code>RecalcMatrix</code> so the UI is only rebuilt when needed. It doesn't touch the UI unless necessary so it should be much faster.</p> <p><strong>Update Again</strong><br> Fixed problem when using <code>Margin</code></p> <p>Is think what you're looking at is basically a <code>WrapPanel</code> with Horizontal Orientation where every element in it is a 1 Column <code>Grid</code>. Each element in a Column then has a corresponding <code>RowDefinition</code> where the <code>Height</code> Property matches an attached property (<code>"WrapHeight"</code>) set on its Child. This Panel would have to be in a <code>Grid</code> itself, with <code>Height="*"</code> and <code>Width="Auto"</code> because the Children should be positioned by the available <code>Height</code> and not care about the available <code>Width</code>.</p> <p>I made an implementation of this which I called a <code>WrapGridPanel</code>. You can use it like this </p> <pre><code>&lt;local:WrapGridPanel&gt; &lt;Button MinHeight="30" local:WrapGridPanel.WrapHeight="Auto"&gt;I'm auto-sized.&lt;/Button&gt; &lt;Button MinHeight="90" local:WrapGridPanel.WrapHeight="*"&gt;I'm star-sized.&lt;/Button&gt; &lt;Button MinHeight="30" local:WrapGridPanel.WrapHeight="Auto"&gt;I'm auto-sized.&lt;/Button&gt; &lt;Button MinHeight="90" local:WrapGridPanel.WrapHeight="*"&gt;I'm star-sized, too!&lt;/Button&gt; &lt;Button MinHeight="30" local:WrapGridPanel.WrapHeight="Auto"&gt;I'm auto-sized.&lt;/Button&gt; &lt;Button MinHeight="30" local:WrapGridPanel.WrapHeight="Auto"&gt;I'm auto-sized.&lt;/Button&gt; &lt;/local:WrapGridPanel&gt; </code></pre> <p><img src="https://i.stack.imgur.com/mD1X6.png" alt="alt text"></p> <p><strong>WrapGridPanel.cs</strong></p> <pre><code>[ContentProperty("WrapChildren")] public class WrapGridPanel : Grid { private WrapPanel m_wrapPanel = new WrapPanel(); public WrapGridPanel() { ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0, GridUnitType.Auto) } ); RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0, GridUnitType.Star) } ); Children.Add(m_wrapPanel); WrapChildren = new ObservableCollection&lt;FrameworkElement&gt;(); WrapChildren.CollectionChanged += WrapChildren_CollectionChanged; DependencyPropertyDescriptor actualHeightDescriptor = DependencyPropertyDescriptor.FromProperty(WrapGridPanel.ActualHeightProperty, typeof(WrapGridPanel)); if (actualHeightDescriptor != null) { actualHeightDescriptor.AddValueChanged(this, ActualHeightChanged); } } public static void SetWrapHeight(DependencyObject element, GridLength value) { element.SetValue(WrapHeightProperty, value); } public static GridLength GetWrapHeight(DependencyObject element) { return (GridLength)element.GetValue(WrapHeightProperty); } public ObservableCollection&lt;FrameworkElement&gt; WrapChildren { get { return (ObservableCollection&lt;FrameworkElement&gt;)base.GetValue(WrapChildrenProperty); } set { base.SetValue(WrapChildrenProperty, value); } } void ActualHeightChanged(object sender, EventArgs e) { RecalcMatrix(); } void WrapChildren_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { RecalcMatrix(); } List&lt;List&lt;FrameworkElement&gt;&gt; m_elementList = null; private bool SetupMatrix() { m_elementList = new List&lt;List&lt;FrameworkElement&gt;&gt;(); double minHeightSum = 0; m_elementList.Add(new List&lt;FrameworkElement&gt;()); int column = 0; if (WrapChildren.Count &gt; 0) { foreach (FrameworkElement child in WrapChildren) { double tempMinHeight = 0.0; if (WrapGridPanel.GetWrapHeight(child).GridUnitType != GridUnitType.Star) { tempMinHeight = Math.Max(child.ActualHeight, child.MinHeight) + child.Margin.Top + child.Margin.Bottom; } else { tempMinHeight = child.MinHeight + child.Margin.Top + child.Margin.Bottom; } minHeightSum += tempMinHeight; if (minHeightSum &gt; ActualHeight) { minHeightSum = tempMinHeight; m_elementList.Add(new List&lt;FrameworkElement&gt;()); column++; } m_elementList[column].Add(child); } } if (m_elementList.Count != m_wrapPanel.Children.Count) { return true; } for (int i = 0; i &lt; m_elementList.Count; i++) { List&lt;FrameworkElement&gt; columnList = m_elementList[i]; Grid wrapGrid = m_wrapPanel.Children[i] as Grid; if (columnList.Count != wrapGrid.Children.Count) { return true; } } return false; } private void RecalcMatrix() { if (ActualHeight == 0 || SetupMatrix() == false) { return; } Binding heightBinding = new Binding("ActualHeight"); heightBinding.Source = this; while (m_elementList.Count &gt; m_wrapPanel.Children.Count) { Grid wrapGrid = new Grid(); wrapGrid.SetBinding(Grid.HeightProperty, heightBinding); m_wrapPanel.Children.Add(wrapGrid); } while (m_elementList.Count &lt; m_wrapPanel.Children.Count) { Grid wrapGrid = m_wrapPanel.Children[m_wrapPanel.Children.Count - 1] as Grid; wrapGrid.Children.Clear(); m_wrapPanel.Children.Remove(wrapGrid); } for (int i = 0; i &lt; m_elementList.Count; i++) { List&lt;FrameworkElement&gt; columnList = m_elementList[i]; Grid wrapGrid = m_wrapPanel.Children[i] as Grid; wrapGrid.RowDefinitions.Clear(); for (int j = 0; j &lt; columnList.Count; j++) { FrameworkElement child = columnList[j]; GridLength wrapHeight = WrapGridPanel.GetWrapHeight(child); Grid.SetRow(child, j); Grid parentGrid = child.Parent as Grid; if (parentGrid != wrapGrid) { if (parentGrid != null) { parentGrid.Children.Remove(child); } wrapGrid.Children.Add(child); } RowDefinition rowDefinition = new RowDefinition(); rowDefinition.Height = new GridLength(Math.Max(1, child.MinHeight), wrapHeight.GridUnitType); wrapGrid.RowDefinitions.Add(rowDefinition); } } } public static readonly DependencyProperty WrapHeightProperty = DependencyProperty.RegisterAttached("WrapHeight", typeof(GridLength), typeof(WrapGridPanel), new FrameworkPropertyMetadata(new GridLength(1.0, GridUnitType.Auto))); public static readonly DependencyProperty WrapChildrenProperty = DependencyProperty.Register("WrapChildren", typeof(ObservableCollection&lt;FrameworkElement&gt;), typeof(WrapGridPanel), new UIPropertyMetadata(null)); } </code></pre> <p><strong>Update</strong><br> Fixed more than one star-sized column problem.<br> New sample app here: <a href="http://www.mediafire.com/?28z4rbd4pp790t2" rel="nofollow noreferrer">http://www.mediafire.com/?28z4rbd4pp790t2</a></p> <p><strong>Update</strong><br> A picture that tries to explain what <code>WrapGridPanel</code> does</p> <p><img src="https://i.stack.imgur.com/UERSF.png" alt="alt text"></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

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