Различные представления/пользовательские элементы управления на каждой вкладке TabControl

Я пытаюсь написать программу, которая использует вкладки для хранения разных пользовательских элементов управления. В настоящее время я хочу, чтобы пользователь нажимал кнопку поиска, создавая новую вкладку, и внутри нее появляется экран поиска. Используя экран поиска, пользователь может выбрать клиентов, а затем открыть их на своих новых вкладках, чтобы пользователь мог их редактировать. Поэтому, если пользователь вошел и отобрал трех клиентов, экран будет иметь четыре вкладки, один для экрана поиска и три вкладки клиента. Он также должен будет закрыть вкладку, когда пользователь нажимает кнопку выхода на usercontrol на этой вкладке.

Моя проблема в том, что я не уверен, как установить это в моей программе. Я создал TabControl и привязал ItemsSource к коллекции viewmodels (которую я могу добавить, когда пользователь добавляет новый экран). Я могу использовать DataTemplateSelector для выбора DataTemplate, который содержит правильный вид, но я не знаю, как установить ресурс представления в мою модель просмотра.

Я делаю это в WPF, и я в настоящее время использую Bxf, чтобы поместить мои viewmodels в представления, и это нормально работает, но я не уверен, как он вписывается в TabControl.

Я пытаюсь придерживаться MVVM, поэтому список просмотров в моей модели view отсутствует.

Кто-нибудь сделал что-то подобное этому раньше?

Ответ 1

Я только что ответил на свой вопрос.

Табиты, которые создаются динамически, настраиваются с помощью datacontext отдельного элемента из свойства items items tabcontrols, в этом случае одна из моих моделей viewmodels.

Используемый мной шаблон данных правильно отображает правильное представление для типа viewmodel и отображает его.

Однако мой взгляд задал datacontext сетки в представлении для моего ресурса, и поэтому ничего не появлялось. Я изменил это, чтобы использовать datacontext вместо ресурса, и теперь все работает.

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

Ответ 2

Я бы сделал мой основной ViewModel похожим на это:

  • ObservableCollection<ViewModelBase> OpenTabs
  • ICommand AddTabCommand
  • ICommand CloseTabCommand

В конструкторе создается новый SearchViewModel и добавляется к OpenTabs, а метод Search получает привязки к некоторому методу в MainViewModel

Метод в MainViewModel, который обрабатывает команду поиска, создаст новый CustomerViewModel с указанным клиентом, установит его CloseCommand, а затем добавит его в OpenTabs

var vm = new CustomerViewModel(customer);
vm.CloseCommand = this.CloseTabCommand;
OpenTabs.Add(vm);

Вы также можете использовать систему событий, такую ​​как PRISM EventAggregator или Galasoft Messenger, чтобы передавать события AddTab/CloseTab вместо подключения команд из MainViewModel

И, конечно, вы бы использовали DataTemplates, чтобы определить, как каждый объект OpenTab будет отображаться в представлении

<TabControl ItemsSource="{Binding OpenTabs}">
    <TabControl.Resources>
        <DataTemplate DataType="{x:Type local:SearchViewModel}">
            <local:SearchView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:CustomerViewModel}">
            <local:CustomerView />
        </DataTemplate>
    </TabControl.Resources>
</TabControl>