Позиционирование элемента табуляции WPF

Как правильно разместить, например, три элемента табуляции в самом верхнем левом углу и один в правом верхнем углу элемента управления вкладками с использованием WPF?

Я попытался переместить четвертую вкладку вправо, изменив ее поле, но это не дало хорошего результата; во-первых, он обрывается, а во-вторых, при выборе он не отображается правильно.


person Daniel    schedule 17.01.2011    source источник


Ответы (4)


Проблема в том, что TabPanel, который используется внутри TabControl для размещения вкладок, похоже, не поддерживает то, что вы хотите. Быстрый обходной путь - заменить TabPanel чем-то другим, например DockPanel:

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <TabControl>
        <TabControl.Template>
            <ControlTemplate TargetType="TabControl">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Border BorderThickness="0,0,1,1" BorderBrush="#D0CEBF" Grid.Row="1">
                        <Border BorderThickness="{TemplateBinding BorderThickness}" 
                                BorderBrush="{TemplateBinding BorderBrush}">
                            <Border Background="{TemplateBinding Background}">
                                <ContentPresenter ContentSource="SelectedContent"/>
                            </Border>
                        </Border>
                    </Border>
                    <DockPanel IsItemsHost="True" LastChildFill="False" Margin="2,2,2,0" />
                </Grid>
            </ControlTemplate>
        </TabControl.Template>

        <TabItem Header="Item 1" />
        <TabItem Header="Item 2" />
        <TabItem Header="Item 3" />
        <TabItem Header="Item 4" DockPanel.Dock="Right" />
    </TabControl>
</Window>

(Ссылка: это модифицированная версия примера MSDN для стилизации TabControl.)

Простая панель DockPanel работает не так гладко, как TabPanel - вкладки немного "прыгают" при переключении между ними, но это может помочь вам начать работу. Возможно, создание подкласса TabPanel и переопределение соответствующих частей даст вам более точный результат; Думаю, это зависит от того, сколько усилий вы хотите приложить для этого.

person Heinzi    schedule 17.01.2011

Я обнаружил, что, вставив «невидимую» вкладку, я могу регулировать интервал (т.е. перемещать вкладки сверху вниз)

Например:

TabItem  Height="100"  Visibility="Hidden" <br>
TabItem..... <br>
TabItem....  <br>
person Kevin Smith    schedule 29.04.2011

Вам нужно будет заменить TabPanel в TabControl на что-то нестандартное, обеспечивающее желаемое поведение. Ни одна из стандартных панелей по умолчанию не будет обеспечивать желаемое поведение вне коробка.

Скорее всего, это потребует переопределения MeasureOverride и ArrangeOverride, чтобы обеспечить настраиваемое размещение внутри панель, которая желательна в зависимости от количества содержащихся в ней элементов.

person Aaron McIver    schedule 17.01.2011

Это будет включать настраиваемый ControlTemplate для TabControl. Я попробовал пример с использованием DockPanel в качестве хоста элементов, а не TabPanel по умолчанию.

<Style  TargetType="{x:Type TabControl}">
        <Setter Property="OverridesDefaultStyle"
                Value="True" />
        <Setter Property="SnapsToDevicePixels"
                Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabControl}">
                    <Grid KeyboardNavigation.TabNavigation="Local">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <DockPanel Name="HeaderPanel"
                                   LastChildFill="False"
                                  Grid.Row="0"
                                  Panel.ZIndex="1"
                                  Margin="0,0,4,-1"
                                  IsItemsHost="True"
                                  KeyboardNavigation.TabIndex="1"
                                  Background="Transparent" />
                        <Border Name="Border"
                                Grid.Row="1"
                                Background="WhiteSmoke"
                                BorderBrush="Black"
                                BorderThickness="1"
                                CornerRadius="2"
                                KeyboardNavigation.TabNavigation="Local"
                                KeyboardNavigation.DirectionalNavigation="Contained"
                                KeyboardNavigation.TabIndex="2">
                            <ContentPresenter Name="PART_SelectedContentHost"
                                              Margin="4"
                                              ContentSource="SelectedContent" />
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Проблема в том, что я не знаю способа раскрыть свойство DockPanel.Dock для TabItems за пределами ControlTemplate E.G.

<TabControl Margin="10">
    <TabItem Header="Tab One" DockPanel.Dock="Left"/>
    <TabItem Header="Tab Two" DocKPanel.Dock="Left"/>
    <TabItem Header="Tab Three" DocKPanel.Dock="Left"/>
    <TabItem Header="Tab Four" DocKPanel.Dock="Right"/>
</TabControl>

// Note: This does not work!!

Я думаю, вам нужно будет написать свою собственную панель для размещения TabItems; Обратите внимание, что это будет довольно много работы, так как вам нужно будет обрабатывать такие вещи, как поведение переполнения, которое встроено в TabPanel.

Даже если вы попробуете это сделать, я думаю, вам придется написать собственный TabControl, если вы хотите предоставить эту функциональность за пределами ControlTemplate.

Если вы хотите пойти по этому пути, посмотрите мой ответ в этом сообщении

person Benjamin Gale    schedule 17.01.2011