有没有办法让 tabcontrol 获取最大选项卡项的大小(实际上是 tabitem 的内容)?

由于选项卡控件没有分配特定的大小,因此它应该自动调整大小:它可以正确地执行此操作,但是当您切换选项卡时,它会自动调整自身大小以适应当前所选选项卡内容的高度(和宽度)。

我不希望发生调整大小,并让 tabcontrol 假定最大项目的高度,但仍然让它自动调整大小。

有什么线索吗?我尝试将数据绑定到 Height 用作使用多重绑定的内容的每个元素的属性,同时绑定在 ActualHeightItems Tab 控件的属性。但可惜的是, ActualHeight 内容元素的个数始终为 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>

            ...

这可以做到吗?

有帮助吗?

解决方案 3

事实上,解决起来比我想象的要容易。因为我有一个控制模板 TabControl 无论如何,我设置了高度 ContentPresenter 显示选定的选项卡内容。我使用绑定到项目的转换器来执行此操作 TabControl, ,必要时测量它们(使用 Measure)和检查 DesiredSize 适合我需要的尺寸。

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

这工作得很好,但有一些注意事项:

  • 每个选项卡内容都应该是 FrameworkElement
  • 内容一旦加载就不会改变大小(因为转换器仅在 Items 属性更改时调用,即仅调用一次)。

其他提示

是它可以做到:重用网格rowdefinitions换每个-TabItem的

示例:

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

问题是 TabControl 当您切换选项卡时卸载并重新加载其内容。因此它只知道当前活动选项卡中内容的大小。您应该能够更改 TabControl 以便它 绝不 摧毁它的孩子,他们总是存在的(但可能是隐藏的)。

这篇博文 埃里克·伯克(Eric Burke)的著作应该可以帮助你入门。据我所知,通过浏览他的帖子,您需要将其更改为:

  • TabControl 已加载。
  • 孩子不活动时是躲起来而不是倒下

这可能不是正确的WPF的方式,但是,如果你已经有了所有的内容元素,你也许可以循环通过他们对用电负荷及编程设置TabControl的高度。

这与上面所示Grid.IsSharedSizeScope方法结合为我工作。

请注意SetCurrentValue使用,而不是仅仅设置SelectedIndex属性 - 这种方式,我们可以保持现有的绑定:

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);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top