2010-06-28 15 views
25

Todavía estoy bromeando con WPF y aprendiendo sobre la marcha. Intentando ahora construir una agrupación dinámica de controles (principalmente Botones pero podría incluir CheckBoxes y otros).WrapPanel como ItemPanel para ItemsControl

No tenía idea de cuál era la mejor manera de hacerlo, así que traté de crear un estilo de control de elementos y luego agregar los elementos en un ItemsPresenter dentro de un WrapPanel. Pronto me di cuenta de que los artículos no se envolverían porque efectivamente no estaban dentro del WrapPanel a menos que lo pusiera como ItemsHost. De esta manera:

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

Tenga en cuenta que esto es un trabajo en progreso y todavía hay muchos efectos de estilo que debo implementar. Aquí lo uso:

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

también destacar que éste es todavía un trabajo en progreso como UniformGrid no sería el camino a seguir aquí y también los márgenes puede ser un dolor (¿existen márgenes que se superponen?) así que la entrada allí sería apreciada.

Ahora al problema real. Esto no funciona me sale un error:

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

¿Cuál es la mejor manera de hacer algo como esto (le encantaría ser capaz de simplemente tirar botones y otros controles en el ItemControl y la alineación muy bonito) . ¿Sería mejor poner los Controles en una colección de algún tipo e iterar?

Me encantaría hacerlo bien, pero todavía faltan mis habilidades de WPF. ¿Hay algún libro de WPF que enseñe más allá de lo básico y muestre cómo los profesionales lo harían realmente?

Respuesta

39

Es posible que desee echar un vistazo a la ItemsPanel propiedad:

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

Ejemplo:

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

Y se puede establecer en un estilo de la siguiente manera:

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

Eso funciona pero no quiero configurarlo en el estilo en lugar de en cada ItemsControl. Pensé que era posible con la propiedad IsItemsHost, pero parece que no funciona. ¿Es esta la única manera? –

+0

Respuesta actualizada con un estilo para ItemsControl – Arcturus

+0

Ah, por supuesto, también puedo agregar este estilo, gracias. Si tiene tiempo, podría ver otras 2 preguntas que aún no se han resuelto. http://stackoverflow.com/questions/3118266/wpf-datatemplate-property-set-at-content http://stackoverflow.com/questions/3004967/how-to-reuse-layouts-in-wpf –

3

No olvides la definición de la propiedad clave IsItemsHost = "True". De lo contrario, ItemsControl no mostrará sus artículos.

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