TabControl ItemTemplate без ItemsSource - PullRequest
       14

TabControl ItemTemplate без ItemsSource

2 голосов
/ 07 марта 2012

Я делаю приложение WPF с TabControl.Вначале у меня был TabControl, связанный с ObservableCollection элементов TabBase, где TabBase - базовый класс для модели представления вкладки:

<TabControl
    IsSynchronizedWithCurrentItem="True"
    ItemsSource="{Binding Tabs}"
    ItemTemplate="{StaticResource ClosableTabTemplate}"
...
public ObservableCollection<TabBase> Tabs { get; private set; }
...
public abstract class TabBase : ViewModelBase
...
public abstract class ViewModelBase : INotifyPropertyChanged
{
    public virtual string DisplayName { get; protected set; }
...
<DataTemplate x:Key="ClosableTabTemplate">
    <DockPanel Width="120">
        <Button
            Command="{Binding Path=CmdClose}"
            Content="X"
            />
        <ContentPresenter 
            Content="{Binding Path=DisplayName}">
        </ContentPresenter>
    </DockPanel>
</DataTemplate>

Но я столкнулся с проблемой, когда я переключаю вкладки, это похоже на текущую вкладкусоздается каждый раз, даже если он уже был открыт ранее.Выполняя поиск в StackOverflow, я нашел решение здесь со ссылкой на здесь .Я заменил использование декларативного ItemsSource динамическим созданием вкладок из кода.Проблема с переключением вкладок была решена, но заголовки вкладок потеряли связь с шаблоном, поэтому вместо заголовка вкладки с надписью и кнопкой закрытия я вижу небольшой заголовок вкладки без чего-либо.Немного поиграв с кодом создания вкладки, я смог восстановить размер вкладки и кнопку закрытия, но без привязки - нет заголовка и кнопка закрытия не работает (5 строк с элементом. Заголовок восстановил исходный размер вкладки):

    private void AddTabItem(TabBase view)
    {
        TabItem item = new TabItem();
        item.DataContext = view;
        item.Content = new ContentControl();
        (item.Content as ContentControl).Focusable = false;
        (item.Content as ContentControl).SetBinding(ContentControl.ContentProperty, new Binding());

        item.Header = new ContentControl();
        (item.Header as ContentControl).DataContext = view;
        (item.Header as ContentControl).Focusable = false;
        (item.Header as ContentControl).SetBinding(ContentControl.ContentProperty, new Binding());
        item.HeaderTemplate = (DataTemplate)FindResource("ClosableTabTemplate");

        tabControl.Items.Add(item);
    }

Вопрос в том, как заставить ItemTemplate работать на TabControl без привязки ItemsSource?

1 Ответ

2 голосов
/ 07 марта 2012

Когда вы явно устанавливаете свой item.Header в ContentControl, HeaderTemplate теперь использует этот объект в качестве своего DataContext. Обычно свойство Header получает ваш ViewModel, а ContentPresenter берет этот (невизуальный) объект и применяет к нему HeaderTemplate. Теперь вы подтолкнули вашу ViewModel на уровень в иерархии, чтобы шаблон не применялся в том же месте, что и данные. Перемещение одного из них должно исправить проблемы с привязкой, но одно или другое может лучше подойти для вашей ситуации:

item.Header = view;

или

(item.Header as ContentControl).ContentTemplate = (DataTemplate)FindResource("ClosableTabTemplate");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...