Domanda

C'è un modo per avere a tabcontrol prendere la dimensione del più grande voce di scheda (beh, in realtà, il tabitem contenuto)?

Dal momento che il controllo tabcontrol non ha dimensioni specifiche assegnate dovrebbe autosize:lo fa correttamente, ma quando si passa schede si ridimensiona automaticamente all'altezza (larghezza) il contenuto della scheda attualmente selezionata.

Non voglio che il ridimensionamento per accadere, e lasciare che il controllo tabcontrol assumere l'altezza della voce più importante, ma ancora autosize stesso.

Eventuali indizi?Ho provato il databinding per il Height la struttura di ogni elemento usato come contenuto per l'utilizzo di un multibinding, con associazioni su entrambi i ActualHeight e il Items proprietà del controllo Tabcontrol.Ma, ahimè, il ActualHeight di elementi di contenuto, è sempre 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>

            ...

Questo può essere fatto?

È stato utile?

Soluzione 3

In realtà, era più facile da risolvere che ho pensato.Da quando ho avuto un controltemplate per il TabControl comunque, ho impostato l'altezza del ContentPresenter presentando la scheda selezionata contenuto.Eseguire questa operazione utilizzando un convertitore che si lega agli elementi di TabControl, misure se necessario (utilizzando Measure) e controlli DesiredSize per le dimensioni di cui ho bisogno.

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

Che funziona bene, con alcune avvertenze:

  • ogni scheda contenuto dovrebbe essere un FrameworkElement
  • i contenuti non cambiano di dimensione, una volta caricato (perché il convertitore viene chiamato solo quando gli Elementi variazioni di proprietà, ovvero solo una volta).

Altri suggerimenti

Sì, si può essere fatto: riuso-griglia-rowdefinitions-per-ogni-tabitem

Esempio:

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

Il problema è che il TabControl scarica e ricarica il suo contenuto, come si cambia schede.Pertanto, si conosce solo la dimensione del contenuto in attivo tab.Si dovrebbe essere in grado di cambiare il TabControl tale che mai distrugge i suoi figli, e sono sempre presente (ma forse nascosto).

Questo post del blog da Eric Burke dovrebbe iniziare.Da quello che posso dire scrematura il suo post, è necessario modificare tale che:

  • Tutti i bambini vengono caricati quando il TabControl viene caricato.
  • I bambini sono nascosti piuttosto che crollò quando sono inattivi

Probabilmente non è corretto WPF modo, ma, se si dispone già di tutti gli elementi di contenuto, si potrebbe forse loop attraverso di loro sul carico e impostare l'altezza del TabControl a livello di programmazione.

Questo ha funzionato per me in collaborazione con Grid.IsSharedSizeScope approccio indicato sopra.

Nota che SetCurrentValue è utilizzato invece di solo il SelectedIndex la struttura, in questo modo manteniamo possibile esistenti associazioni:

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top