如何将WPF选项卡项标题拉伸到父控件宽度

Ben*_*err 30 wpf xaml tabs controls stretch

在XAML中是否有一种方法可以使标签项标题在选项卡控件的宽度上伸展?

例如,我有三个选项卡:红色,蓝色和绿色.如果我有一个宽度设置为auto的标签控件,标签页眉只会填充标签内容上方的部分空间,但我希望它们填满所有空间.对于我的三个标签示例,红色应该占据控制的前三分之一,蓝色应该占据中心的第三个,并且绿色最后的第三个.

我知道如何在我现在正在处理的代码中执行此操作,但我有兴趣以最简单的方式执行此操作.

Rya*_*saw 48

我拿了乔丹的例子并做了一些修改.此版本适用于任意数量的选项卡:

namespace WpfApplication1.Converters
{
    public class TabSizeConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            TabControl tabControl = values[0] as TabControl;
            double width = tabControl.ActualWidth / tabControl.Items.Count;
            //Subtract 1, otherwise we could overflow to two rows.
            return (width <= 1) ? 0 : (width - 1);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
            System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

xaml中的相同命名空间:

xmlns:local="clr-namespace:WpfApplication1.Converters"
Run Code Online (Sandbox Code Playgroud)

这将使所有标签使用它:

<Window.Resources>
    <local:TabSizeConverter x:Key="tabSizeConverter" />
    <Style TargetType="{x:Type TabItem}">
        <Setter Property="Width">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource tabSizeConverter}">
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor,
            AncestorType={x:Type TabControl}}" />
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor,
            AncestorType={x:Type TabControl}}" Path="ActualWidth" />
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

  • 当使用这个tabitems堆叠在彼此的顶部,但如果我将(宽度 - 1)更改为(宽度 - 2.1)然后它"工作",但我似乎在tabitems的任一侧有一个像素空间.我做得不对的东西? (4认同)
  • 当标签项的数量<= 3时,我得到与@ChrisHDog相同的结果.四个及以上它的效果很好.我把结果改为:`return(width <= 1)?0 :(宽度 - 1.34);`这似乎照顾了所有数量的标签项. (3认同)
  • @RyanVersaw:为什么不实现 IValueConverter 而不是 IMultiValueConverter? (2认同)
  • 它是“IMultiValueConverter”而不是“IValueConverter”的原因是,如果没有第二个绑定到“ActualWidth”,则绑定将在呈现控件之前绑定,导致“ActualWidth”在转换器内始终为零。将第二个绑定添加到 `ActualWidth` 会强制绑定在每次父级 `TabControl` 的宽度发生变化时重新计算。这有点麻烦,但它有效。 (2认同)

Cha*_*lie 18

每个人似乎都在转换路径,但它实际上就像在模板中UniformGrid使用Rows设置为1 一样简单,而不是.当然,你必须重新模板化,但这并不算太糟糕.TabControlTabPanel

  • 对于那些喜欢复制和粘贴的人来说,这样的一个例子会很好:) (3认同)

小智 6

我能够使用像这样的转换器:

namespace WpfApplication1.Converters
{
    public class SizeConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            double width = Double.Parse(value.ToString());
            //Subtract 1, otherwise we could overflow to two rows.
            return .25 * width - 1;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        #endregion
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将命名空间添加到我的xaml:

xmlns:local="clr-namespace:WpfApplication1.Converters"
Run Code Online (Sandbox Code Playgroud)

然后使所有TabItems使用转换器:

<Window.Resources>
        <local:SizeConverter x:Key="sizeConverter" />
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="Width" Value="{Binding ElementName=x_Grid, Path=ActualWidth, Converter={StaticResource sizeConverter}}" />
        </Style>
    </Window.Resources>
Run Code Online (Sandbox Code Playgroud)

x_Grid是x:父元素的名称我希望标签是1/4,如果这是有道理的.


Ale*_*x G 6

我是一个老派风格的人。并且更喜欢将这种功能封装到控件本身的代码中。我的派生控件如下所示:

    public class CustomTabControl :TabControl
{
    protected override void OnRenderSizeChanged(System.Windows.SizeChangedInfo sizeInfo)
    {
        foreach (TabItem item in this.Items)
        {
            double newW = (this.ActualWidth / Items.Count) - 1;
            if (newW < 0) newW = 0;

            item.Width = newW;
        }            
    }       
}
Run Code Online (Sandbox Code Playgroud)

我的 XAML 看起来像

</infrastructure:CustomTabControl>
     <TabItem />
     <TabItem />
</infrustracture:CustomControl>
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么每个人都更喜欢样式控制而不是派生。