tags:

views:

25

answers:

1

Simplified problem.

I have two ItemsControls that are located one under another and are bound to the same sequence:

[Control] [Another Control] [More Controls]
[Other Ctrl] [Super Control] [Control]

What I would like to do is align their sizes such that they appear to be a single table:

[Control   ] [Another Control] [More Controls]
[Other Ctrl] [Super Control  ] [Control      ]

It would also be acceptable to go "one-way": make bottom items same size as top ones, even if they are shorter:

[Control] [Another Control] [More Controls]
[Other C] [Super Control  ] [Control      ]

A few considerations:

  1. Yes, they have to be in separate ItemControls.
  2. No, I cannot use Grid or DataGrid.
  3. I fully own the back-end data structures (if that helps)

For a more complete explanation, one can refer to my other question.

UPDATE: Why do they have to be in different ItemControls
In general, what I'm trying to achieve is to build a table that is bound to a rectangular data structure. I do not see any way to do this other than using nested ItemControls: one ItemControl for rows, each item containing another ItemControl for cells in that row. Or vice versa: one for columns, each item containing cells in that column. Either way, nested items will have to be aligned to each other.
I do realize that there may be other way to create such a table that I do not see. Which is why I also asked the other question.

Thank you, oh almighty community, in advance.

A: 

Try the following:

 <StackPanel Grid.IsSharedSizeScope="True">
    <StackPanel.Resources>
        <DataTemplate x:Key="SharedSizeTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="SharedSize"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding}"/>
            </Grid>
        </DataTemplate>
    </StackPanel.Resources>
    <ItemsControl ItemTemplate="{StaticResource SharedSizeTemplate}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <System:String>One</System:String>
        <System:String>Longer</System:String>
        <System:String>Longest</System:String>
        <System:String>Very Longest</System:String>
    </ItemsControl>
    <ItemsControl ItemTemplate="{StaticResource SharedSizeTemplate}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <System:String>Short</System:String>
        <System:String>S</System:String>
        <System:String>Even longer than above</System:String>
        <System:String>V</System:String>
    </ItemsControl>
</StackPanel>

EDIT: There is still one problem though - all columns will be sized to the same optimum width - don't know if you can live with that?

Goblin
Wow, thanks a lot! Honestly, I was already starting to think that I'll have to create/manage UI elements manually. And it's ok with all columns being same width: I can actually create separate string IDs for each column, put them into my data structure, and bind the `SharedSizeGroup` properties of appropriate columns to that `ColumnID` property, thus making them all different size.
Fyodor Soikin
However, this creates another problem: as soon as I put a `SharedSizeGroup` property on a `ColumnDefinition`, that column stops stretching all the way to fill the available space. I need, you see, to have the last column stretch to the end. Any ideas on how to get that?
Fyodor Soikin
Hmm... then you need to mess around with a DataTemplateSelector - that based on the items' position in the list switch between two DataTemplates... This might get messy... Or implement a custom Panel for the ItemsPanelTemplate - let me know which you prefer and I'll update with a sample.
Goblin
I don't get the idea with DataTemplateSelector. Suppose I choose another template for the last item in the row. And what do I do then? How do I get that item to stretch, but still keep it in the shared size group?
Fyodor Soikin
The point is that for the second DataTemplate - the width isn't set to Auto, but rather to "*" so that it stretches to the side. It doesn't matter that it isn't in the sharedsizegroup since it will use the remaining space (which should be the same for the two itemscontrols).
Goblin