2

In Windows Forms, placing items into a FlowLayoutPanel control works very much the same way as using a WrapPanel in Windows Presentation Foundation (WPF).

Items in a FlowLayoutPanel can have the FlowBreak property set to true to indicate that the panel should move to the beginning of the next row after the item, regardless of how much space remains in the current row. Basically it's saying "line break after this".

I am now using WPF for a project and I need to know how I accomplish the equivalent when using a WPF WrapPanel control.

I already know how to do this with brute force. I'm hoping there is a more elegant and simple method. Any ideas?

Mike Fulton
  • 920
  • 11
  • 22

1 Answers1

1

You can use this trick:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<WrapPanel x:Name="mywrappanel">
    <TextBox Text="Text1"/>
    <TextBox Text="Text2"/>
    <TextBox Text="Text3"/>
    <Border Width="{Binding Path=ActualWidth, ElementName=mywrappanel}"/>
    <TextBox Text="Text4"/>
    <TextBox Text="Text5"/>
</WrapPanel>
</Page>

What it is doing is using a dummy element with no height (so that it is "hidden") but with a width that matches the WrapPanel so you can be sure it can't fit on the current row, and "fills" the next one.

You can use any FrameworkElement derived element as the dummy...just choose a lightweight one to avoid unnecessary memory usage.

You can use a binding that uses RelativeSource if you don't want to have to name your WrapPanel e.g.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<WrapPanel x:Name="mywrappanel">
    <TextBox Text="Text1"/>
    <TextBox Text="Text2"/>
    <TextBox Text="Text3"/>
    <Border Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type WrapPanel}}}"/>
    <TextBox Text="Text4"/>
    <TextBox Text="Text5"/>
</WrapPanel>
</Page>

To better visualize what it's doing...just give it a height and some colour.

<Page
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<WrapPanel x:Name="mywrappanel">
    <TextBox Text="Text1"/>
    <TextBox Text="Text2"/>
    <TextBox Text="Text3"/>
    <Border Height="20" Background="Red" Width="{Binding Path=ActualWidth, ElementName=mywrappanel}"/>
    <TextBox Text="Text4"/>
    <TextBox Text="Text5"/>
</WrapPanel>
</Page>

enter image description here

If you want your XAML to be a bit cleaner/clearer (i.e. not have the binding, and dummy Border), then you could create your own FrameworkElement that's designed to always match the width of an ancestor WrapPanel.

See the NewLine element here:

Community
  • 1
  • 1
Colin Smith
  • 12,375
  • 4
  • 39
  • 47