2010-06-28 8 views
25

Immer noch herumalbern mit WPF und lernen, wie ich gehe. Versuchen Sie jetzt, eine dynamische Gruppierung von Steuerelementen zu erstellen (meistens Buttons, aber möglicherweise CheckBoxes und andere).WrapPanel als ItemPanel für ItemsControl

Ich hatte keine Ahnung, was der beste Weg war, dies zu tun, also habe ich versucht, einen ItemsControl-Stil zu erstellen und dann die Elemente in einen ItemsPresenter in einem WrapPanel einzufügen. Bald stellte sich heraus, dass die Elemente nicht umgebrochen wurden, weil sie nicht innerhalb des WrapPanels waren, es sei denn, ich habe es als ItemsHost angegeben. Gefällt mir:

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

Beachten Sie, dass dies ein Work in Progress ist und es viele Styling-Effekte gibt, die ich noch implementieren muss. Hier habe ich es verwenden:

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

Auch hier beachten Sie, dass es immer noch ein work in progress ist als Uniform nicht den Weg wäre hier zu gehen und kann auch die Margen ein Schmerz (gibt es irgendwelche Ränder, die sich überlappen?) so würde dort Eingang geschätzt werden.

Jetzt zum wirklichen Problem. Das funktioniert nicht, ich einen Fehler:

'ItemsPresenter' object cannot be added to 'WrapPanel'. Cannot explicitly modify Children collection of Panel used as ItemsPanel for ItemsControl. ItemsControl generates child elements for Panel. Error at object 'System.Windows.Controls.ItemsPresenter'.

Also, was ist der beste Weg, um so etwas zu tun (würde gerne in der Lage sein, nur Tasten zu werfen und andere Steuerelemente in die ItemControl und die Line-up wirklich schön) . Wäre es besser, die Controls in eine Art von Sammlung zu bringen und zu iterieren.

Würde es lieben, es schön gemacht zu bekommen, aber meine WPF-Fähigkeiten fehlen noch. Gibt es irgendwelche WPF-Bücher, die über die Grundlagen hinaus lehren und zeigen, wie Profis es wirklich tun würden?

Antwort

39

Sie vielleicht einen Blick auf die ItemsPanel Eigenschaft nehmen wollen:

Gets or sets the template that defines the panel that controls the layout of items.

Beispiel:

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

Und Sie es in einem Stil festgelegt wie folgt:

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

Das funktioniert, aber ich möchte es auf den Stil anstatt auf jede ItemsControl setzen. Ich dachte, das wäre mit der IsItemsHost-Eigenschaft möglich, scheint aber nicht zu funktionieren. Ist das der einzige Weg? –

+0

Aktualisierte Antwort mit einem Style für ItemsControl – Arcturus

+0

Ah natürlich kann ich auch einfach in diesen Stil hinzufügen, danke. Wenn Sie Zeit haben, können Sie sich 2 andere Fragen ansehen, die ich noch nicht gelöst habe. http://stackoverflow.com/questions/3118266/wpf-datatemplate-property-set-at-content http://stackoverflow.com/questions/3004967/how-to-reuse-layouts-in-wpf –

3

Vergessen Sie nicht die Definition der Hinweiseigenschaft IsItemsHost = "True". Andernfalls zeigt ItemsControl Ihre Artikel nicht an.

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