让WPF Tabcontrol高度假设最大项目的高度?

时间:2009-07-02 11:11:12

标签: wpf height tabcontrol multibinding

有没有办法让tabcontrol获取最大标签项的大小(实际上,tabitem的内容)?

由于tabcontrol没有指定特定的大小,因此它应该自动调整大小:它可以正确执行,但是当您切换标签时,它会自动调整其大小,使其自动调整为当前所选标签内容的高度(和宽度)。

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

任何线索?我尝试数据绑定到使用多绑定作为内容的每个元素的Height属性,并对Tabcontrol的ActualHeightItems属性进行绑定。但是,内容元素的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>

            ...

可以这样做吗?

5 个答案:

答案 0 :(得分:22)

是的,可以这样做:reuse-grid-rowdefinitions-for-each-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>

答案 1 :(得分:6)

问题是TabControl在切换标签时卸载并重新加载其内容。因此,它只知道当前活动选项卡中内容的大小。您应该能够更改TabControl,使其永远不会销毁其子项,并且它们始终存在(但可能隐藏)。

Eric Burke的

This blog post应该让你开始。通过略读他的帖子我可以告诉你,你需要改变它:

  • 加载TabControl时,所有子项都已加载。
  • 儿童在不活动时隐藏而不是崩溃

答案 2 :(得分:5)

实际上,我认为这更容易解决。 由于我无论如何都有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

这很好,有一些警告:

  • 每个标签内容都应为{{1}}
  • 加载后内容不会改变大小(因为转换只在Items属性更改时调用,即只调用一次)。

答案 3 :(得分:1)

它可能不是正确的WPF方式,但是,如果您已经拥有所有内容元素,则可以在加载时循环遍历它们并以编程方式设置TabControl的高度。

答案 4 :(得分:1)

这对我来说与上面显示的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); } 属性 - 这样我们就可以保留现有的绑定:

{{1}}