Выпадающий TabControl - PullRequest
       27

Выпадающий TabControl

1 голос
/ 23 сентября 2010

Я пытался создать собственный скин / шаблон для TabControl в WPF.

Я хочу, чтобы вкладки отображались в ComboBox.Когда вы выбираете элемент в ComboBox, я хочу, чтобы в области содержимого элемента управления вкладками отображалось содержимое TabItem.

Вот изображение, показывающее то, что я ищу:

alt text

Я мог бы сделать это с помощью некоторой настройки мастер-детализации с объектами данных и шаблонами, но проблема в том, что я хочу настроить элементы управления с использованием формата TabControl XAML, например:

<TabControl Style="{DynamicResource ComboTabControlStyle}">
   <TabItem Header="TabItem1">
      <TextBlock Text="TabItem1 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
   </TabItem>
   <TabItem Header="TabItem2">
      <TextBlock Text="TabItem2 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
   </TabItem>
   <TabItem Header="TabItem3">
      <TextBlock Text="TabItem3 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
   </TabItem>
</TabControl>

Есть какие-нибудь мысли или предложения?

Очень легко изменить расположение элементов вкладки, используя другую панель, но ComboBox - это ItemsControl, а не Panel.

Я попытался поместить ComboBox в шаблон TabControl и связать ItemsSource ComboBox со свойством TabControl.Items, но, похоже, он работал неправильно.

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

У кого-нибудь есть другие идеи?

Спасибо за помощь!

Ответы [ 3 ]

1 голос
/ 23 сентября 2010

Удивительно сложно делать то, что ты пытаешься сделать. Это очень близко:

<DockPanel>
    <ComboBox x:Name="ItemSelector" DockPanel.Dock="Top">
        <ComboBox.ItemTemplate>
            <DataTemplate DataType="{x:Type TabItem}">
                <TextBlock Text="{Binding Header}"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
        <TabItem Header="TabItem1">
            <TextBlock Text="TabItem1 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </TabItem>
        <TabItem Header="TabItem2">
            <TextBlock Text="TabItem2 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </TabItem>
        <TabItem Header="TabItem3">
            <TextBlock Text="TabItem3 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </TabItem>      
    </ComboBox>
    <ContentPresenter Content="{Binding SelectedItem.Content, ElementName=ItemSelector}" DockPanel.Dock="Top"/>
    <TextBlock/>
</DockPanel>

Там, где он ломается, как ни странно, отображается выбранный элемент в ComboBox: ItemTemplate игнорируется при рендеринге элемента, поэтому поле выбора содержит TabItem. Чтобы исправить это , вам нужно создать подкласс ComboBox и реализовать свойство зависимостей SelectionBoxItemTemplate для чтения / записи, потому что, по некоторым причинам, я уверен, что это не так глупо, как мне кажется в данный момент, это свойство только для чтения.

0 голосов
/ 23 сентября 2010

Я нашел решение.

Я создал собственный класс Control (MasterDetailControl).

Этот класс состоит из двух частей шаблона:

[TemplatePart(Name = "PART_MasterSelector", Type = typeof(Selector))]
[TemplatePart(Name = "PART_DetailPresenter", Type = typeof(ContentPresenter))]

Элемент управления имеет свойство зависимости элементов:

public IList Items { ... }

Я добавил вспомогательный класс:

[ContentProperty("Detail")]
public class MasterDetail
{
   public object Master { get; set; }
   public object Detail { get; set; }
}

Элементы, помещенные в DP Items, обрабатываются MasterDetailControl. Если они имеют тип MasterDetail, мастер добавляется в список элементов селектора. Для других типов дочерних элементов создается новый объект MasterDetail с объектом, назначенным полям master и detail. В отдельном списке хранятся все сгенерированные объекты MasterDetail с индексами, соответствующими индексам в элементе управления Selector.

Когда событие SelectionChanged срабатывает на объекте Selector, я присваиваю свойству ContentPresenter значение Content в поле Detail элемента, соответствующего выбранному главному объекту.

Если кому-то нужна более подробная информация, не стесняйтесь комментировать.

В конце я теперь могу использовать этот элемент управления с простым шаблоном элемента управления, определяющим любой объект селектора (ListBox, ComboBox и т. Д.) И ContentPresenter.

0 голосов
/ 23 сентября 2010

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

Вы должны использовать собственный класс для написания вкладок, поскольку они являются обычными элементами вкладок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...