Pregunta

Todavía jugando con WPF y aprendiendo sobre la marcha. Tratando ahora de construir una dinámica agrupación de los controles (en su mayoría, pero podría incluir botones casillas de verificación y otros).

Yo no tenía idea de lo que era la mejor manera de hacer esto así que he intentado crear un estilo ItemsControl y luego añadir los elementos en una ItemsPresenter dentro de un WrapPanel. Pronto se dio cuenta de que los artículos no se envuelva, ya que efectivamente no estaban dentro de la WrapPanel menos que poner 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 este es un trabajo en progreso y hay muchos efectos de estilo que aún no han aplicado. 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 tenga en cuenta aquí que 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?) Por lo que de entrada no sería apreciada.

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

  

objeto 'ItemsPresenter' no se puede añadir a 'WrapPanel'. No puedo   modificar explícitamente colección de los niños de Panel utiliza como ItemsPanel para   ItemsControl. ItemsControl genera elementos secundarios para el Panel. Error   en el objeto '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 y iterate.

Me encantaría conseguir que bien hecho pero mis habilidades WPF todavía faltan. ¿Hay algún libro de WPF que enseñan más allá de los conceptos básicos y muestran cómo pro de verdad lo haría?

¿Fue útil?

Solución

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

  

Obtiene o establece la plantilla que define el panel que controla la disposición de los elementos.

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>

Otros consejos

No se olvide de definición de la propiedad pista IsItemsHost = "true". De lo contrario su ItemsControl no mostrará sus artículos.

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

Aquí hay otra alternativa sencilla para frenar Xceed cuadrícula de datos y solución de cuadrícula de datos / WrapPanel. Podría ser útil cuando una gran cantidad de datos o toda la tabla es sólo para la edición. El uso de ItemsControl + Grid.IsSharedSizeScope = "true"

Más información aquí: https://wpf.2000things.com/tag/issharedsizescope/ + En ItemsControl virutualization para el rendimiento: virtualización de una 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>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top