Элементы управления XAML: видимость презентатора контента не отражает каждый принадлежащий элемент

В ItemsControl элементы находятся в ContentPresenter, поэтому, если элемент имеет Visibility='collapsed', его ContentPresenter по-прежнему имеет Visibility='Visible'... (Здесь объясняется это поведение)

Таким образом, эти 2 примера не показывают тот же результат:

Это работает, как я ожидаю:

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

Это не работает, как я ожидаю (UniformGrid резервирует место для третьей кнопки, даже если она свернута):

<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>

Кто-нибудь получил эту проблему? Есть ли обходной путь?


person Andrea Marchetto    schedule 26.10.2018    source источник


Ответы (1)


Это ожидаемое поведение, потому что кнопка не является прямым дочерним элементом UniformGrid. Вместо этого ItemsControl добавляет шаблон ContentPresenter с DataTemplate, который вы определили, к UniformGrid. Таким образом, визуальное дерево выглядит примерно так:1

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

Я думаю, это ясно демонстрирует, почему место в сетке зарезервировано, даже если кнопка свернута. Конечно, чтобы исправить это, вы должны вместо этого свернуть ContentPresenter. Этого можно добиться, используя свойство ItemsControl.ItemContainerStyle:

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

1 Предоставленный код является только иллюстрацией визуального дерева и не является допустимым WPF XAML.

person Grx70    schedule 28.10.2018
comment
Да, вы правы: это решение... Я надеялся, что есть альтернативное решение, потому что я бы предпочел иметь возможность определить общий ItemContainerStyle, чтобы повторно использовать его... Вместо этого я должен определить это специально для модели, которую я использую. - person Andrea Marchetto; 05.11.2018