Различные представления/пользовательские элементы управления на каждой вкладке 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>