1

In ItemsControl items are in a ContentPresenter, so if a item has Visibility='collapsed' its ContentPresenter still have Visibility='Visible'... (Here is explained this behaviour)

So these 2 examples doesn't show the same result:

This works as I expect:

<UniformGrid Columns="1">
    <Button Content="0"/>
    <Button Content="1"/>
    <Button Content="2" Visibility="Collapsed"/>
    <Button Content="3"/>
</UniformGrid>

This doesn't work as I expect (UniformGrid reserve the space for the third button also if it is collapsed):

<ItemsControl>
    <ItemsControl.ItemsSource>
        <x:Array Type="{x:Type System:Int32}">
            <System:Int32>0</System:Int32>
            <System:Int32>1</System:Int32>
            <System:Int32>2</System:Int32>
            <System:Int32>3</System:Int32>
        </x:Array>
    </ItemsControl.ItemsSource>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Visibility="{Binding ., Converter={StaticResource CalculatorConverter}, ConverterParameter=IIF(\{0\}\=2\,\'Collapsed\'\,\'Visible\')}" Content="{Binding .}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Anyone got this problem? Is there a workaround?

1 Answer 1

1

This is expected behaviour, because the button is not a direct child of the UniformGrid. Instead, ItemsControl adds a ContentPresenter templated with the DataTemplate you've defined to the UniformGrid. So basically the visual tree resembles this:1

<UniformGrid>
    ....
    <ContentPresenter>
        <Button Visibility="Collapsed" />
    </ContentPresenter>
    ....
</UniformGrid>

I think this clearly demonstrates why the space in the grid is reserved even though the button is collapsed. Of course to remedy that you should collapse the ContentPresenter instead. It can be achieved by using ItemsControl.ItemContainerStyle property:

<ItemsControl>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="{x:Type ContentPresenter}">
            <Setter Property="Visiblity" Value="{Binding ., Converter=...}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    ...
</ItemsControl>

1 The provided code is only an illustration of the visual tree and is not a valid WPF XAML.

1
  • Yes, you're right: this is the solution ... I was hoping there was an alternative solution because I would have preferred to be able to define generic "ItemContainerStyle" in order to reuse it ... Instead in this way I have to define it specifically for the model I'm using. Commented Nov 5, 2018 at 8:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.