2012-03-03 3 views
7

У меня есть TabControl в моем приложении WPF. Я хочу, чтобы мое приложение в основном поддерживало несколько «экземпляров» в рамках одной программы. Например, подумайте о веб-браузерах, они позволяют иметь несколько экземпляров веб-сайтов на разных вкладках, я хочу добиться аналогичной функциональности, когда мое приложение содержит несколько экземпляров «подпрограмм».Как создать вкладку в WPF/C#?

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

Вот скриншот моего приложения в его текущем состоянии. Как вы можете видеть, в верхней части находятся 2 вкладки, а второй - прозрачный фон, так как он неактивен.

enter image description here

Итак, как создать табуляцией состоянии системы, в которой пользовательский интерфейс вкладки остается одинаковой для каждой вкладки и мне нужно только разработать с одной XAML UI и дублировать для каждой вкладки?

Требования:

  • Каждая вкладка имеет один и тот же интерфейс.
  • Каждая вкладка имеет разные данные для элементов пользовательского интерфейса.
  • Как разработчик, я хочу работать с XAML вкладки только один раз и прямо в Visual Studio.

В идеале мне бы понравился простой простой пример проекта/кода, в котором есть один элемент управления с незакрепленным вкладом, а приложение при запуске динамически создает 2-n вкладки, все из которых имеют один и тот же интерфейс, но с разными данными.

ответ

3

Как отмечалось в другом ответе есть, вероятно, много способов сделать это, но вот мой простой способ:

Определить DataTemplate, который определяет содержание каждого ваших одинаковых вкладок. Элементы управления в шаблоне данных будут привязаны к модели представления текущей выбранной вкладки. В моем примере я поставил один TextBlock, но вы можете легко расширить его.

с помощью этого Xaml:

<Page.DataContext> 
    <Samples:TabBindingViewModels /> 
</Page.DataContext> 

<Grid> 
    <Grid.Resources> 
     <DataTemplate x:Key="ContentTemplate" 
         DataType="{x:Type Samples:TabBindingViewModel}"> 
      <TextBlock Text="{Binding Content}"/> 
     </DataTemplate> 
    </Grid.Resources> 
    <TabControl ContentTemplate="{StaticResource ContentTemplate}" 
       DisplayMemberPath="Header" ItemsSource="{Binding Items}" /> 
</Grid> 

и этот вид код модели:

public class TabBindingViewModels 
{ 
    public TabBindingViewModels() 
    { 
     Items = new ObservableCollection<TabBindingViewModel> 
        { 
         new TabBindingViewModel(1), 
         new TabBindingViewModel(2), 
         new TabBindingViewModel(3), 
        }; 
    } 

    public IEnumerable<TabBindingViewModel> Items { get; private set; } 
} 

public class TabBindingViewModel 
{ 
    public TabBindingViewModel() : this(0) 
    { 
    } 

    public TabBindingViewModel(int n) 
    { 
     Header = "I'm the header: " + n.ToString(CultureInfo.InvariantCulture); 
     Content = "I'm the content: " + n.ToString(CultureInfo.InvariantCulture); 
    } 

    public string Header { get; set; } 
    public string Content { get; set; } 
} 

мы получаем:

enter image description here

Я очень нравится эта tutorial на стилизации вкладок , Вы можете легко добавить более сложный контент в заголовки вкладок, а также в контент.

Вы должны изучить полный шаблон элемента управления вкладки, чтобы получить представление о том, как он работает. Для извлечения шаблона используйте Blend или VS11 beta.

Чтобы динамически добавлять/удалять вкладки, теперь все, что вам нужно сделать, это добавить/удалить элементы в модели ObservableCollection для просмотра.

2

Это может фактически превратиться в довольно большой ответ, потому что есть много разных путей, которые вы могли бы предпринять.

Важно понимать, что TabControl - это ItemsControl, что означает, что он может содержать коллекцию объектов, таких как UserControls, которые составляют каждый модуль. Таким образом, вы можете начать с привязки свойства Items к ObservableCollection{T} некоторых объектов UserControl, которые живут внутри некоторого проекта модуля, который реализует интерфейс, такой как IModule от Prism. Интерфейс определяет начальную точку любого модуля, который может быть загружен на вкладке. Поскольку модули запрашиваются, вы просто загружаете сборку и добавляете вкладку, содержащую ссылку на область, определенную в модуле.

Это на самом деле не очень сложно, но я бы рекомендовал вам прочитать на Prism, потому что он будет обрабатывать много тяжелой работы для вас. Недавно я прошел через создание интерфейса точно так же, как тот, который вы описываете с помощью Prism.

+0

Интересно, я даже не знал о Призме. – Tower

+0

Есть ли примеры демонстрационных приложений, которые я мог бы посмотреть? – Tower

+1

К сожалению, я ничего не знаю, и мое приложение не является открытым исходным кодом. Краткое руководство по началу работы здесь может помочь вам приступить к работе. Если вы застряли, не стесняйтесь задавать новый вопрос. ;-) Я обещаю, что это не так сложно, как только вы займетесь этим. http://msdn.microsoft.com/en-us/library/ff921153(v=pandp.40).aspx#sec15 – senfo

1

Посмотрите на Caliburn.Micro для решения на основе рамки MVVM. Точный вопрос, который вы задаете, решается в одном из типовых решений.

http://caliburnmicro.codeplex.com/

+0

Есть ли у него какие-то требования? Я попытался открыть многие образцы в VS 2011, и большинство из них жаловалось на отсутствие сборок, и я даже исправил некоторые из них, добавив вручную из папки Silverlight bin, но он все еще жалуется, например. 'Свойство 'Dock' не существует в типе 'StackPanel' в пространстве имен XML 'clr-namespace: System.Windows.Controls; assembly = System.Windows.Controls.Toolkit''. Вы помните, какой образец точно отвечает на мой вопрос --- тогда я могу продолжать пытаться исправить этот конкретный образец :) – Tower

+0

@rFactor, имя образца было Caliburn.Micro.SimpleMDI. Это один из немногих проектов, отличных от Silverlight, в списке образцов. У меня все еще есть VS 2010, и он загружается и работает отлично. – code4life

+0

Я предполагаю, что вы не разблокировали почтовый файл перед распаковкой. Щелкните правой кнопкой мыши zip и выберите свойства. Нажмите кнопку «разблокировать». Теперь разархивируйте его. Вы, вероятно, найдете, что все будет намного лучше. – Phil

1

Без дополнительной информации, мой подход был бы запуск поставщика MVVM внутри ApplicationDomain для каждого экземпляра или вкладки. Когда вы убиваете/закрываете вкладку, выгрузите домен приложения.

Смежные вопросы