Question

Est-il possible d'avoir à prendre tabcontrol la taille du plus grand élément de l'onglet (bien, en fait, le contenu du TabItem)?

Depuis la tabcontrol n'a pas de taille spécifique attribué devrait autoSize:. Il le fait correctement, mais quand vous Buttées il se redimensionne automatiquement à la hauteur (et largeur) du contenu de l'onglet sélectionné

Je ne veux pas le redimensionnement se produise, et laisser le tabcontrol la hauteur assumer le poste le plus important, mais encore il s'autoSize.

Les indices? J'essayé liaison de données à la Height propriété de chaque élément utilisé en tant que contenu à l'aide d'un MultiBinding, avec les fixations à la fois sur le ActualHeight et les propriétés de la Items tabcontrol. Mais hélas, le des éléments <=> de contenu est toujours 0.

        <TabItem Header="Core" > 
            <Grid Margin="5">
                <Grid.Height>
                    <MultiBinding Converter="{Converters1:AllTabContentEqualHeightConverter}">
                        <Binding Path="ActualHeight" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}"/>
                        <Binding Path="Items" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}"/>
                    </MultiBinding>
                </Grid.Height>

            ...

peut-il être fait?

Était-ce utile?

La solution 3

En fait, il était plus facile à résoudre que je pensais. Depuis que j'avais un ControlTemplate pour la TabControl de toute façon, je régler la hauteur de la présentation du contenu ContentPresenter onglet sélectionné. Je le fais en utilisant un convertisseur qui se lie aux éléments de la Measure, les mesures, le cas échéant (en utilisant DesiredSize) et vérifie la taille FrameworkElement j'ai besoin.

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var items = value as ItemCollection;

        if (items == null)
            return null;

        double max = 0;
        foreach (TabItem item in items)
        {
            var content = item.Content as FrameworkElement;
            if (content == null) continue;

            if (!content.IsMeasureValid)
                content.Measure(new Size(int.MaxValue, int.MaxValue));

            var height = content.DesiredSize.Height;
            if (max < height)
                max = height;
        }

        return max;
    }

Cela fonctionne très bien, avec quelques mises en garde:

  • chaque contenu onglet doit être <=>
  • le contenu ne change pas de taille une fois qu'ils sont chargés (parce que le convertisseur est appelé uniquement lorsque les changements de propriété des éléments, à savoir une fois).

Autres conseils

Oui il peut être fait: réutilisation grille-rowdefinitions-pour-chaque-TabItem

Exemple:

    <TabControl Grid.IsSharedSizeScope="True">
        <TabItem Header="Tab 1">
            <Grid >
                <Grid.RowDefinitions>
                    <RowDefinition SharedSizeGroup="xxx"/>
                </Grid.RowDefinitions>
            </Grid>
        </TabItem>
        <TabItem Header="Tab 2">
            <Grid >
                <Grid.RowDefinitions>
                    <RowDefinition SharedSizeGroup="xxx"/>
                </Grid.RowDefinitions>
            </Grid>
        </TabItem>
   </TabControl>

Le problème est que les TabControl est déchargé et rechargé son contenu que vous Buttées. Par conséquent, il ne connaît que de la taille du contenu de l'onglet actif. Vous devriez être en mesure de changer la TabControl telle qu'elle jamais détruit ses enfants, et ils sont toujours présents (mais peut-être caché).

Ce blog par Eric Burke devrait vous aider à commencé. D'après ce que je peux dire par écrémage son poste, vous devrez changer de telle sorte que:

  • Tous les enfants sont chargés lorsque le chargement <=>.
  • Les enfants sont cachés plutôt que effondré quand ils sont inactifs

Il est sans doute pas de la bonne façon WPF, mais, si vous avez déjà tous les éléments de contenu, vous pourriez peut-être en boucle à travers eux la charge et de régler la hauteur du TabControl programatically.

Cela a fonctionné pour moi en collaboration avec l'approche Grid.IsSharedSizeScope ci-dessus.

Notez que SetCurrentValue est utilisé au lieu de mettre juste la propriété SelectedIndex - cette façon, nous gardons possibles les liaisons existantes:

private void TabControl_OnLoaded(object sender, RoutedEventArgs e)
{
    //NOTE: loop through tab items to force measurement and size the tab control to the largest tab
    TabControl tabControl = (TabControl)sender;

    // backup selection
    int indexItemLast = tabControl.SelectedIndex;

    int itemCount = tabControl.Items.Count;

    for (
        int indexItem = (itemCount - 1);
        indexItem >= 0;
        indexItem--)
    {
        tabControl.SetCurrentValue(Selector.SelectedIndexProperty, indexItem);
        tabControl.UpdateLayout();
    }

    // restore selection
    tabControl.SetCurrentValue(Selector.SelectedIndexProperty, indexItemLast);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top