WrapPanel en tant Qu'Empanel pour ItemsControl

toujours en train de batifoler avec WPF et d'apprendre au fur et à mesure. Essayer MAINTENANT de construire un groupement dynamique de contrôles (principalement des boutons mais peut inclure des cases à cocher et d'autres).

Je n'avais aucune idée de ce qui était la meilleure façon de le faire donc j'ai essayé de créer un style ItemsControl et puis Ajouter les éléments dans un ItemsPresenter à l'intérieur d'un WrapPanel. J'ai vite réalisé que les objets ne s'emballaient pas parce qu'ils n'étaient pas dans le WrapPanel à moins que je ne le mette comme posture. Pareil:

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

notez que c'est un travail en cours et il y a beaucoup d'effets de style que je dois encore mettre en œuvre. Ici je l'utilise:

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

aussi noter ici que c'est encore un travail en cours car UniformGrid ne serait pas la voie à suivre ici et aussi les marges peuvent être une douleur (y a-t-il des marges qui se chevauchent?) de sorte que l'entrée il y aurait apprécié.

maintenant au vrai problème. Cela ne fonctionne pas je reçois une erreur:

l'objet "ItemsPresenter" ne peut pas être ajouté à "WrapPanel". Ne peut pas modifier explicitement la collection Enfants De panneau utilisé comme élément Spanel pour ItemsControl. ItemsControl génère des éléments enfants pour le Panneau. Erreur à l'objet du Système.Windows.Contrôle.ItemsPresenter".

alors quelle est la meilleure façon de faire quelque chose comme ça ( j'aimerais pouvoir juste jeter des boutons et d'autres contrôles dans le ItemControl et la ligne jusqu'à très bien ). Serait-il préférable de mettre les contrôles dans une sorte de collection et itérer.

serait ravi de le faire bien fait, mais mes compétences WPF font encore défaut. Y a-t-il des livres du WPF qui enseignent au-delà des bases et montrent comment les pros le feraient vraiment?

25
demandé sur Cœur 2010-06-28 15:26:58

3 réponses

vous pourriez vouloir jeter un oeil à la ItemsPanel propriété:

Obtient ou définit le modèle qui définit le panneau qui contrôle la disposition des éléments.

exemple:

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

Et vous pouvez le définir dans un Style comme suit:

<Style TargetType="ItemsControl">
    <Setter Property="ItemsPanel">
      <Setter.Value>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
</Style>
40
répondu Arcturus 2010-06-28 13:35:49

N'oubliez pas de définition de l'idée de propriété IsItemsHost="True". Sinon, votre ItemsControl ne montrera pas vos articles.

<ListBox ItemsSource="{Binding MyItemsSource}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate >
                <WrapPanel IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ListBox>
3
répondu Mr.B 2016-03-08 11:06:08

voici une autre alternative simple à la solution lente DataGrid / xceed datagrid et WrapPanel. Peut être utile quand beaucoup de données ou un tableau entier est juste pour l'édition. En Utilisant ItemsControl + Grid.IsSharedSizeScope= "True"

plus d'informations ici: https://wpf.2000things.com/tag/issharedsizescope / + Sur ItemsControl virutualization pour la performance: Virtualiser un ItemsControl?

<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>
0
répondu Evalds Urtans 2018-07-26 14:58:01