让WPF自定义的Tabcontrol高度承担最大项目的高度?(Let WPF Tabcontrol

2019-06-24 17:54发布

有没有办法不得不采取TabControl的最大标签项(当然,实际上,该TabItem的内容)的大小?

由于的tabcontrol具有分配应该AUTOSIZE没有具体的尺寸:它的正确,但是当你切换标签它本身自动调整大小,以当前所选选项卡的内容的高度(和宽度)。

我不想调整大小的情况发生,并让TabControl的假设的最大项目的高度,但仍然有它本身自动调整大小。

任何线索? 我试图数据绑定到Height用作内容的使用multibinding,与上都绑定到每个元素的属性ActualHeightItems的自定义的Tabcontrol的性质。 但很可惜,在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>

            ...

可以这样做?

Answer 1:

是的,它可以做到: 重用并网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>


Answer 2:

问题是,在TabControl卸载,当你切换标签重新加载其内容。 因此,只知道在当前激活标签的内容的大小。 您应该能够改变TabControl的,使得它永远不会破坏它的孩子,他们总是存在(但也许隐藏)。

本博客文章由埃里克·伯克应该让你开始。 从我可以通过略读他的帖子出来,你需要改变这样的:

  • 当将所有的孩子都被加载TabControl被加载。
  • 儿童被隐藏,而不是崩溃了,当他们处于非活动状态


Answer 3:

其实,这是比较容易解决,我认为。 因为我有一个的ControlTemplate中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
  • 一旦被加载(因为当项目属性改变,即只有一次转换器只调用)中的内容不会改变大小。


Answer 4:

它可能不是在正确的WPF的方式,但是,如果你已经有了所有的内容元素,你可以通过它们的负载可能环和设置的高度TabControl编程。



Answer 5:

这与一起工作对我来说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);
}


文章来源: Let WPF Tabcontrol height assume height of largest item?