Подтвердить что ты не робот

WrapPanel как ItemPanel для ItemsControl

Все еще обманывать WPF и учиться, когда я иду. Теперь попытаемся создать динамическую группировку элементов управления (в основном кнопки, но могут включать CheckBox и другие).

Я понятия не имел, как лучше всего это сделать, поэтому я попытался создать стиль ItemsControl, а затем добавить элементы в ItemPresenter внутри WrapPanel. Вскоре поняли, что элементы не будут обертываться, потому что они фактически не были внутри WrapPanel, если я не поставил его как ItemsHost. Вот так:

<Style x:Key="ButtonPanelGroup" TargetType="{x:Type ItemsControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ItemsControl}">
                <Border CornerRadius="5"
                        BorderBrush="{StaticResource DarkColorBrush}"
                        BorderThickness="1"
                        Margin="5">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>

                        <WrapPanel IsItemsHost="True" FlowDirection="LeftToRight">
                            <ItemsPresenter />
                        </WrapPanel>

                        <ContentPresenter ContentSource="Name" Grid.Row="1" />

                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Обратите внимание, что это незавершенная работа, и есть много эффектов моделирования, которые мне еще нужно реализовать. Здесь я использую его:

<UniformGrid Rows="1">
    <ItemsControl Name="Group1" Style="{StaticResource ButtonPanelGroup}">
        <Button>Button1</Button>
        <Button>Button2</Button>
        <CheckBox>TickBox</CheckBox>
    </ItemsControl>

    <ItemsControl Name="Group2" Style="{StaticResource ButtonPanelGroup}">
        <Button>Button3</Button>
        <Button>Button4</Button>
        <Button>Button5</Button>
    </ItemsControl>

    <ItemsControl Name="Group3" Style="{StaticResource ButtonPanelGroup}">
        <Button>Button6</Button>
        <Button>Button7</Button>
        <Button>Button8</Button>
    </ItemsControl>
</UniformGrid>

Также обратите внимание на то, что все еще продолжается работа, так как UniformGrid не может быть здесь, а также поля могут быть болью (есть ли какие-либо поля, которые перекрываются?), поэтому вход будет оценен.

Теперь к реальной проблеме. Это не работает. Я получаю сообщение об ошибке:

Объект ItemsPresenter не может быть добавлен в 'WrapPanel'. Не могу явное изменение коллекции Children для Panel, используемой как ItemsPanel для ItemsControl. ItemsControl генерирует дочерние элементы для Panel. ошибка в объекте "System.Windows.Controls.ItemsPresenter".

Итак, что лучший способ сделать что-то подобное (хотелось бы, чтобы вы могли просто набрасывать кнопки и другие элементы управления в ItemControl, и линия действительно хороша). Было бы лучше поставить Controls в какую-то коллекцию и повторить ее.

Хотелось бы сделать это красиво, но мои навыки WPF все еще не хватает. Есть ли какие-либо книги WPF, которые учат за пределами основ и показывают, как профессионалы действительно это сделают?

4b9b3361

Ответ 1

Вы можете взглянуть на свойство ItemsPanel:

Получает или задает шаблон, который определяет панель, которая управляет компоновкой элементов.

Пример:

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

И вы можете установить его в стиле следующим образом:

<Style TargetType="ItemsControl">
    <Setter Property="ItemsPanel">
      <Setter.Value>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
</Style>

Ответ 2

Не забывайте определение свойства clue IsItemsHost = "True". В противном случае ваш ItemsControl не будет показывать ваши элементы.

<ListBox ItemsSource="{Binding MyItemsSource}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate >
                <WrapPanel IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ListBox>