WrapPanel: attempt to make ItemWidth equal to the maximum width of any item

I hope no one has asked this question yet, but I searched and cannot find a mention. Feel free to point me in the right direction if I missed another question that explains this.

I have a WrapPanel with data-bound elements that essentially contain a variable-length icon and text (this is a legend for the chart). I really like that items appear in neat columns when I set ItemWidth to some given value. However, due to the high variability of the text length in each element, I can not easily select a specific value that will work for all cases. That is, in some cases, the text for all elements may be short, so a lower value for ItemWidth would be appropriate. But in other cases, such a small ItemWidth will result in truncated text among some items.

I believe that I can bind ItemWidth to the WrapPanel in some way to extract the width of each item (and find the maximum width, and use it as ItemWidth, etc.), but I cannot do this because of the data binding potential to the wrong thing. As with binding to something that changes when ItemWidth changes, which leads to infinite loops (or at least loops that repeat more time than necessary).

What is the best way to set this so that ItemWidth is as large as necessary to prevent truncation?

EDIT:

I want to keep the function offered by WrapPanel, which allows you to have a variable number of columns of elements, depending on the space allowed for the WrapPanel itself.

+7
c # data-binding wpf
source share
3 answers

You can wrap each element in a Grid and use the ShareSizeScope Grid property to make sure that all elements have the same width.

For example, on your WrapPanel, you would set Grid.IsSharedSizeScope to true

 <WrapPanel Grid.IsSharedSizeScope="True"> 

Then you move each element into a single Grid cell, which uses the SharedSizeGroup property to tell them that they all have a common size

 <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="SharedGroup" /> </Grid.ColumnDefinitions> <ContentPresenter /> </Grid> 

If you need an example, a quick Google search gave me this answer , which contains sample code.

I would recommend performance testing if you have a large dataset.

+7
source share

Try the following. The part to pay attention to is the Grid.IsSharedSizeScope = "True" in the wrapper panel and the SharedSizeGroup property of the column definition.

 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <WrapPanel Grid.IsSharedSizeScope="True"> <WrapPanel.Resources> <Style TargetType="TextBlock"> <Setter Property="Padding" Value="2" /> <Setter Property="HorizontalAlignment" Value="Center" /> </Style> </WrapPanel.Resources> <WrapPanel.Children> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="abcdefghijklmnopqrstuvwxyz" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="1234567890" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="abcdefghijklmnopqrstuvwxyz" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="1234567890" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="abcdefghijklmnopqrstuvwxyz" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="1234567890" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="abcdefghijklmnopqrstuvwxyz" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="1234567890" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="abcdefghijklmnopqrstuvwxyz" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="1234567890" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="abcdefghijklmnopqrstuvwxyz" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="1234567890" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="abcdefghijklmnopqrstuvwxyz" /> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="group1" /> </Grid.ColumnDefinitions> <TextBlock Text="1234567890" /> </Grid> </WrapPanel.Children> </WrapPanel> </Grid> </Window> 
+1
source share

try setting the itemwidth property to Auto ... see here:

http://msdn.microsoft.com/en-us/library/system.windows.controls.wrappanel.itemwidth(v = vs .110) .aspx

To perform this β€œwidth set” programmatically, you can do the following as soon as the control is rendered.

 protected override void OnRender(DrawingContext dc) { int largest = 0; foreach(UIElement child in this.myWrapPanel.Children) { if(child.Width>largest) largest = child.Width; } this.myWrapPanel.ItemWidth = largest; } 
0
source share

All Articles