Frage

Gibt es eine Möglichkeit zu haben tabcontrol die Größe des größten Registerkarte Punktes nehmen (na ja, tatsächlich, die TabItem Inhalt)?

Da die tabcontrol hat keine spezifische Größe zugewiesen sollte es autosize:. Es das tut richtig, aber wenn Sie Registerkarten wechseln Verändern der Größe sich automatisch auf die Höhe (und Breite) der Inhalt des aktuell ausgewählten Registerkarte

Ich will nicht die Redimensionierung passieren, und lassen Sie die die Höhe des größten Posten tabcontrol annehmen, aber immer noch haben sie sich autosize.

Irgendwelche Hinweise? Ich versuchte Datenbindung an die Height Eigenschaft jedes als Inhalt verwendet Element an der einen mehrbindigen Verwendung mit Bindungen sowohl auf der ActualHeight und den Eigenschaften des Items tabcontrol. Aber ach, die ActualHeight der Inhaltselemente ist immer 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>

            ...

Kann dies geschehen?

War es hilfreich?

Lösung 3

Eigentlich war es leichter zu lösen, dass ich dachte. Da ich sowieso einen Control für die TabControl hatte, habe ich die Höhe des ContentPresenter den ausgewählten Registerkarte Inhalt zu präsentieren. Ich tue dies mit einem Konverter, der auf die Elemente des TabControl bindet, misst sie bei Bedarf (mit Measure) und prüft DesiredSize für die Größe ich brauche.

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

Das ist ganz gut, mit einigen Einschränkungen funktioniert:

  • sollte jeder Registerkarte Inhalt ein FrameworkElement sein
  • die Inhalte nicht ändern Größe, sobald sie geladen sind (weil der Konverter nur, wenn die Eigenschaft Items Änderungen, dh nur einmal aufgerufen wird).

Andere Tipps

Ja, es kann getan werden: Wiederverwendung-Grid-rowdefinitions-für-jeden-TabItem

Beispiel:

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

Das Problem ist, dass der TabControl leert und lädt seinen Inhalt wie Sie Registerkarten wechseln. Daher nur er weiß um die Größe des Inhalts in den aktuell aktiven Registerkarte. Sie sollten die TabControl, so dass sie sich ändern können, nie zerstört seine Kinder, und sie sind immer vorhanden ist (aber vielleicht versteckt).

Dieser Blog-Eintrag von Eric Burke sollten Sie gestartet. Von dem, was ich durch Abschöpfen seinen Posten sagen kann, müssen Sie es ändern, so dass:

  • Alle Kinder sind geladen, wenn das TabControl geladen wird.
  • Kinder sind versteckt und nicht kollabiert, wenn sie inaktiv sind

Es ist wahrscheinlich in der richtigen Art und Weise WPF nicht, aber, wenn Sie bereits alle Elemente Inhalt haben, könnten Sie vielleicht durch sie auf Lastschleife und stellen Sie die Höhe des TabControl programmatisch.

Dies ist für mich in Verbindung mit Grid.IsSharedSizeScope Ansatz oben gezeigt.

Beachten Sie, dass SetCurrentValue verwendet wird, anstatt nur die SelectedIndex-Eigenschaft - auf diese Weise wir möglich, bestehende Bindungen halten:

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);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top