35 votes

Disposition dynamique WPF avec ItemsControl et Grid

Je suis entrain de créer un formulaire WPF. L'une des conditions est qu'il ont un secteur de base de mise en page afin qu'un contrôle peut être explicitement placé dans l'un des secteurs ou des cellules.

J'ai créé un tic-tac-toe exemple ci-dessous pour transmettre mon problème:

Il existe deux types et un type de base:

public class XMoveViewModel : MoveViewModel
{
}
public class OMoveViewModel : MoveViewModel
{
}
public class MoveViewModel
{
    public int Row { get; set; }
    public int Column { get; set; }
}

Le DataContext de la forme est définie à une instance d':

public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        Moves = new ObservableCollection<MoveViewModel>()
        {
            new XMoveViewModel() { Row = 0, Column = 0 },
            new OMoveViewModel() { Row = 1, Column = 0 },
            new XMoveViewModel() { Row = 1, Column = 1 },
            new OMoveViewModel() { Row = 0, Column = 2 },
            new XMoveViewModel() { Row = 2, Column = 2}
        };
    }
    public ObservableCollection<MoveViewModel> Moves
    {
        get;
        set;
    }
}

Et enfin, le code XAML ressemble à ceci:

 <Window.Resources>
    <DataTemplate DataType="{x:Type vm:XMoveViewModel}">
        <Image Source="XMove.png" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Column}" Stretch="None" />
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:OMoveViewModel}">
        <Image Source="OMove.png" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Column}" Stretch="None" />
    </DataTemplate>
</Window.Resources>
<Grid>
    <ItemsControl ItemsSource="{Binding Path=Moves}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid ShowGridLines="True">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Grid>

Ce qui n'était pas évident pour moi quand j'ai commencé a que le ItemsControl élément encapsule chaque élément dans un conteneur, donc ma Grille.Ligne et de la Grille.Les liaisons de colonne sont ignorées, puisque les images ne sont pas directement contenue dans la grille. Ainsi, toutes les images sont placées dans le défaut de Ligne et de Colonne (0, 0).

Ce qui se passe:

What is happening

Le résultat souhaité:

The desired result

Donc, ma question est la suivante: comment puis-je obtenir le placement dynamique des mes contrôles dans une grille? Je préfère une XAML/Liaison de Données/MVVM-solution à l'amiable.

Merci.

J'ai mis le code final ici: http://www.centrolutions.com/downloads/TicTacToe.zip

29voto

Charlie Points 9880

Vous êtes sur la bonne voie. Il vous suffit de créer un Style et de l'appliquer au ItemsControl.ItemContainerStyle . Ensuite, dans le style, spécifiez un setter pour Grid.Row et Grid.Column . Le ItemContainerStyle sera appliqué aux conteneurs générés pour chaque élément.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X