Wrappanel как itempanel для itemscontrol
-
01-10-2019 - |
Вопрос
Все еще дурачиться с WPF и обучение, как я иду. Сейчас пытаясь создать динамическую группировку управления (в основном кнопки, но может включать флажки и другие).
Я понятия не имел, что был лучшим способом сделать это, поэтому я попытался создать элементы Control STYLE, а затем добавлять элементы в элементыPresenter внутри Wrappanel. Вскоре понял, что предметы не будут обернуть, потому что они эффективно не были внутри WRAPPANEL, если я не помещаю его как itempshost. Так:
<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>
Также отметьте здесь, что это все еще работа в прогрессе, так как униформантность не будет таким, как сюда идет сюда, а также поля могут быть болью (есть ли небольшая края, которая перекрывается?) Так будет оценена.
Теперь к реальной проблеме. Это не работает, я получаю ошибку:
Объект «PerficationPresenter» нельзя добавить в «Wrappanel». Не удается явно модифицировать дети коллекции панели, используемую в качестве элементовPanel для элементовControl. ItemsControl генерирует дочерние элементы для панели. Ошибка на объекте 'System.windows.controls.itemspresenter'.
Итак, какой лучший способ сделать что-то подобное (хотел бы, чтобы иметь возможность просто бросать кнопки и другие элементы управления в ItemControl и выстроиться на очень хорошее). Было бы лучше поставить контроль в коллекцию какой-то итерации.
Хотел бы получить это красиво сделать, но мои навыки WPF по-прежнему отсутствуют. Есть ли какие-либо книги WPF, которые учат за пределы основы и показывают, как Pro's действительно это сделает?
Решение
Возможно, вы захотите взглянуть на PerficationPanel имущество:
Получает или задает шаблон, который определяет панель, которая управляет макетом элементов.
Пример:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
И вы можете установить его в стиле следующим образом:
<Style TargetType="ItemsControl">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
Другие советы
Не забывайте определение имущества подсказки ISTemshost = «True». В противном случае ваши элементыControl не покажут ваши вещи.
<ListBox ItemsSource="{Binding MyItemsSource}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate >
<WrapPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ListBox>
Вот еще одна простая альтернатива медленному решению DataGrid / XEC-DataGrid и Wrappanel. Может быть полезен, когда многие данные или целый стол просто для редактирования. Использование itemsControl + Grid.issharedSizescope = "True"
Больше информации здесь: https://wpf.2000things.com/tag/issharedsizescope/+ На элементы контролируют вирутуализацию для производительности: Виртуализация элементов контроля?
<Grid Grid.IsSharedSizeScope="True" Margin="0,30,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="50" Width="Auto" SharedSizeGroup="Id" />
<ColumnDefinition MinWidth="50" Width="Auto" SharedSizeGroup="Time" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" >
<TextBlock VerticalAlignment="Center" TextWrapping="NoWrap" Text="Header1" />
</Border>
<Border Grid.Column="1" >
<TextBlock VerticalAlignment="Center" TextWrapping="NoWrap" Text="Header2" />
</Border>
</Grid>
<ItemsControl Grid.Row="1" ItemsSource="{Binding RunInstance.ConcentrationGradient.Steps}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="50" Width="Auto" SharedSizeGroup="Id" />
<ColumnDefinition MinWidth="50" Width="Auto" SharedSizeGroup="Time" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0">
<TextBlock VerticalAlignment="Center" TextWrapping="NoWrap" Text="{Binding Index, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
</Border>
<Border Grid.Column="1">
<TextBlock VerticalAlignment="Center" TextWrapping="NoWrap" Text="{Binding Time, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>