35

XAML でタブ項目ヘッダーをタブ コントロールの幅全体に広げる方法はありますか?

たとえば、赤、青、緑の 3 つのタブがあります。幅が自動に設定されたタブ コントロールがある場合、タブ ヘッダーはタブ コンテンツの上のスペースの一部だけを埋めますが、すべてのスペースを埋めたいと思います。私の 3 つのタブの例では、赤はコントロールの最初の 3 分の 1 を占め、青は中央の 3 分の 1 を占め、緑は最後の 3 分の 1 を占めます。

現在取り組んでいるコードの背後でこれを行う方法を考えていますが、これを可能な限り簡単な方法で行うことに興味があります。

4

12 に答える 12

55

ジョーダンの例を参考にして、それにいくつかの変更を加えました。このバージョンは、任意の数のタブで機能するはずです。

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

xaml の同じ名前空間:

xmlns:local="clr-namespace:WpfApplication1.Converters"

これにより、すべてのタブでそれが使用されます。

<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>
于 2009-04-29T21:36:04.820 に答える
23

誰もがコンバーター ルートを使用しているように見えますが、実際にはテンプレートで with を 1 に設定して . の代わりにUniformGrid使用Rowsするのと同じくらい簡単です。もちろん、テンプレートを再作成する必要がありますが、これはそれほど悪いことではありません。TabControlTabPanel

于 2014-03-26T00:07:24.537 に答える
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
    }
}

次に、名前空間をxamlに追加します。

xmlns:local="clr-namespace:WpfApplication1.Converters"

次に、すべてのTabItemにコンバーターを使用させます。

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

x_Gridは、親要素のx:Nameです。意味がある場合は、タブを1/4にします。

于 2009-04-29T19:05:09.987 に答える
2

以下に示すように、親タブ コントロールの ActualWidth に幅をバインドすることで可能になります。

すべてのタブ ページに適用するスタイルでラップしました。

<Grid>
      <Grid.Resources>
        <Style TargetType="TabItem">
            <Setter Property="Width" Value="{Binding    
                     Path=ActualWidth,    
                     RelativeSource={RelativeSource    
                    Mode=FindAncestor,    
                    AncestorType={x:Type TabControl}}}"/>
        </Style>
    </Grid.Resources>

<TabControl>
    <TabItem Header="Page3"/>
    <TabItem Header="Page2"/>
    <TabItem Header="Page3"/>            
</TabControl> 
</Grid>
于 2009-04-04T18:07:22.777 に答える
0

タブで機能するかどうかはわかりませんが、コンテナを埋めるために何かを伸ばす必要があるときはいつでもViewBoxを使用しました。それはあなたが探しているものですか?

于 2009-04-01T16:05:21.043 に答える
0

等しい tabItem ヘッダー幅を与える Ryan Versaw の受け入れられたソリューションに加えて、各ヘッダーの長さに依存させる次の方法を見つけました。

まず、この行を xaml マルチバインディングに追加して、各 tabItem ヘッダーの文字列を取得します。したがって、次のようになります。

<MultiBinding Converter="{StaticResource tabSizeConverter}">
           <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" />
           <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" Path="ActualWidth" />
           <Binding Path="Header" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>

そして、コンバーターのもう少しのコード (values[] は tabItem ヘッダーも取得します):

public object Convert(object[] values, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        TabControl tabControl = values[0] as TabControl;

        string AllHeaders = "";
        for (int i = 0; i < tabControl.Items.Count; i++)
        {
            int index = tabControl.Items[i].ToString().IndexOf("Header:") + "Header:".Length;
            string currentHeader = tabControl.Items[i].ToString().Substring(index);
            currentHeader = currentHeader.Substring(0, currentHeader.Length - " Content:".Length);
            AllHeaders += currentHeader;
        }

        //Normalize width according to header length
        double width = values[2].ToString().Length * tabControl.ActualWidth / AllHeaders.Length;

        //Subtract 1, otherwise we could overflow to two rows.
        var retVal = (width <= 1) ? 0 : (width - 1);
        return retVal;
    }

すべてのヘッダーの AllHeaders 文字列を取得するより効率的な方法があるのではないかと思いますが、そのままで問題なく動作します...

于 2014-08-12T12:29:41.357 に答える
0

私は次の解決策を使用しています: メイン ウィンドウではウィンドウのサイズ変更イベントを使用し、タブコントロールの初期化イベントでは各タブの幅を設定します。「5」という数字は、私のタブの数に対応しています。

    private void tabchanger_Initialized(object sender, EventArgs e)
    {
        foreach (TabItem item in tabchanger.Items)
        {
            double newW = (tabchanger.ActualWidth / 5) - 1;
            if (newW < 0) newW = 0;

            item.Width = newW;
        }

    }

    private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        foreach (TabItem item in tabchanger.Items)
        {
            double newW = (tabchanger.ActualWidth / 5) - 1;
            if (newW < 0) newW = 0;

            item.Width = newW;
        }
    }
于 2015-01-21T18:13:17.147 に答える