Question

J'ai un DockPanel que je remplis dynamiquement à l'aide d'un ItemsControl pour remplir le panneau. Le DockPanel a besoin du dernier enfant de la liste de ItemsControl pour remplir le reste du panneau, mais il ne semble pas se produire si je le remplir de cette façon ... Que puis-je faire pour obtenir ce dernier élément à développer?

extrait de la façon dont je l'ai mis en place: (note que je mets l'arrière-plan DockPanel bleu pour que je puisse distinguer les commandes utilisateur peuplées de l'arrière-plan du panneau)

        <DockPanel Background="Blue" LastChildFill="True" Margin="0">
        <ItemsControl ItemsSource="{Binding Requirements}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <local:TMGrid2View Baseline="{Binding}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </DockPanel>

Mon hypothèse actuelle quant à ce qui se passe est l'enfant de remplissage est appliqué à la ItemsControl au lieu des enfants au sein de la population ItemsControl. Je l'ai utilisé setters dans le passé pour spécifier l'enfant devrait accoster à un côté du panneau, par exemple ... mais il ne semble pas être une option setter de l'enfant pour obtenir son expansion ...

Était-ce utile?

La solution

Ce qui se passe est que votre DockPanel est rempli de ItemsControl. Jusqu'ici tout va bien. Cependant, ItemsControl utilise en interne un StackPanel qui ne peut pas remplir verticalement (horizontalement si elle est définie à l'orientation = « horizontal ».

EDIT:. Pour expliquer l'arrière-plan est bleu ... Le fond du ItemsControl est définie sur null par défaut

Savez-vous combien d'articles est dans la collection?

EDIT2: Ce que vous devez faire quand sa collection de la dynamique ajouter ce qui suit:

<ItemsControl ...>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <!-- rest of ItemsControl properties -->
</ItemsControl>

La grille uniforme attribue une quantité égale de l'espace pour chaque cellule à la fois horizontalement et verticalement et les échanges ItemsPanel la norme StackPanel pour le positionnement.

EDIT3: Travailler avec des éléments de hauteur non égale ... un panneau personnalisé:

public class CustomPanel : StackPanel
{
    protected override Size ArrangeOverride(Size finalSize)
    {
        var childUIElements = Children.OfType<UIElement>().ToList();
        foreach (var child in childUIElements)
        {
            child.Measure(finalSize);
        }
        double remainingHeight = finalSize.Height - childUIElements.Sum(c => c.DesiredSize.Height);
        if(remainingHeight <= 0)
            return base.ArrangeOverride(finalSize);

        double yOffset = 0;
        foreach (var child in childUIElements)
        {
            double height = child.DesiredSize.Height + remainingHeight/childUIElements.Count;
            child.Arrange(new Rect(0,yOffset,finalSize.Width,height));
            yOffset += height;
        }
        return finalSize;
    }
}

Si je ne l'ai pas fait trop de f ..- ups qui devrait faire une version brute au moins. Si les éléments sont grands pour être contenu, il fonctionne comme un StackPanel normal - sinon, il arrange les enfants de diviser l'espace restant à parts égales entre eux. Vous pouvez régler à l'affecter par rapport si vous en avez besoin (ie. Les grands blocs obtenir plus de l'espace restant).

LAST EDIT (je pense :-)) Vous avez besoin de mettre ce panneau personnalisé à l'intérieur du ItemsPanelTemplate au lieu du UniformGrid je l'ai suggéré plus tôt.

Autres conseils

Ne pas mettre le ItemsControl dans le DockPanel; mettre le DockPanel dans le ItemsControl. Utilisez le ItemsPanelTemplate pour faire la ItemsControl pondre ses articles dans un DockPanel.

Utilisez le ItemContainerStyle pour définir la propriété de DockPanel.Dock sur les conteneurs d'éléments (qui, pour un ItemsControl, sera ContentPresenters).

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <ItemsControl Margin="5">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <DockPanel LastChildFill="True"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
      <Style TargetType="ContentPresenter">
        <Setter Property="DockPanel.Dock" Value="Top"/>
      </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <TextBlock Background="Lavender" Margin="1" Padding="5" Text="{Binding}"/>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
    <sys:String>Athos</sys:String>
    <sys:String>Porthos</sys:String>
    <sys:String>Aramis</sys:String>
    <sys:String>D'Artagnan</sys:String>
  </ItemsControl>
</Page>

Avez-vous défini la propriété DockPanel.Dock à la valeur que vous vouliez?

Je vais jeter une solution inélégante:

dans le modelview, Chop la liste de liaison dans une liste contenant tous, mais le dernier élément, puis le dernier élément séparément. Utilisez ensuite le contrôle d'éléments pour la liste et ajouter manuellement une entrée supplémentaire reliant au dernier élément. Je déteste cela, si nous l'espérons il y a une façon meilleure.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top