Я создаю свой первый WPF с использованием шаблона MVVM. С помощью этого сообщества мне удалось создать мою модель, мою первую ViewModel и представление. Теперь я хочу добавить некоторую сложность в приложение, разрабатывающее базовый интерфейс макета приложения. Моя идея состоит в том, чтобы иметь как минимум 2 дочерних вида и один основной вид и разделить их на несколько XAML:
- Main.XAML
- Products.XAML
- Clients.XAML
В главном меню есть меню и пространство для загрузки дочерних представлений (Продукты и Клиенты). Теперь, следуя шаблону MVVM, вся логика навигации между представлениями должна записываться в ViewModel. Итак, идея mi состоит в том, чтобы иметь 4 ViewModels:
- MainViewModel
- ProductsViewModel
- ClientsViewModel
- NavigationViewModel
Итак, NavigationViewModel должен содержать набор дочерних моделей просмотра? и активная модель просмотра - это правильно?
Итак, мои вопросы:
1) Как загрузить различные представления (Продукты, Клиенты) в главном представлении с использованием шаблона MVVM?
2) Как реализовать навигацию viewModel?
3) Как я могу контролировать максимальное количество открытых или активных просмотров?
4) Как я могу переключаться между открытыми представлениями?
Я делал много поиска и чтения и не мог найти простой рабочий пример навигации MVVM с WPF, который загружает несколько видов внутри основного вида. Многие из них:
1) Используйте внешний инструментарий, который я не хочу использовать прямо сейчас.
2) Поместите весь код для создания всех представлений в одном файле XAML, что не кажется хорошей идеей, потому что мне нужно реализовать около 80 просмотров!
Я на правильном пути здесь? Любая помощь, особенно с некоторым кодом, будет оценена.
UPDATE
Итак, я создаю тестовый проект, следующий за советами @LordTakkera, но застрял. Вот как выглядит мое решение:
Я создаю:
Две модели (клиенты и продукты)
Один MainWindow и два пользовательских элемента управления wpf (клиенты и продукты) XAML.
Три модели ViewModels (клиенты, продукты и основная модель просмотра)
Затем я устанавливаю dataContext для каждого представления в соответствующий viewModel. После этого я создаю MainWindow с ContentPresenter, как это, и привязываю его к свойству viewmodel.
MainWindow.xaml
<Window x:Class="PruevaMVVMNavNew.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="519" Width="890">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.ColumnSpan="2" Background="AntiqueWhite" ></Border>
<Border Grid.Row="1" Grid.RowSpan="2" Background="AliceBlue"></Border>
<Border Grid.Row="1" Grid.Column="1" Background="CadetBlue"></Border>
<ContentPresenter Grid.Row="1" Grid.Column="1" x:Name="ContentArea" Content="{Binding CurrentView}"/>
<StackPanel Margin="5" Grid.Column="0" Grid.Row="1">
<Button>Clients</Button>
<Button>Products</Button>
</StackPanel>
</Grid>
А также это viewmodel из MainWindow:
class Main_ViewModel : BaseViewModel
{
public Main_ViewModel()
{
CurrentView = new Clients();
}
private UserControl _currentView;
public UserControl CurrentView
{
get
{
return _currentView;
}
set
{
if (value != _currentView)
{
_currentView = value;
OnPropertyChanged("CurrentView");
}
}
}
}
Таким образом, эта загрузка по умолчанию открывается клиентами и выглядит так (это правильно!):
Итак, я полагаю, мне нужен способ связать кнопки слева, с определенной viemodel, а затем привязать их к CurrentView Property Main viewModel. Как я могу это сделать?
UPDATE2
В соответствии с советом @LordTakkera я изменяю свой основной видModel следующим образом:
class Main_ViewModel : BaseViewModel
{
public ICommand SwitchViewsCommand { get; private set; }
public Main_ViewModel()
{
//CurrentView = new Clients();
SwitchViewsCommand = new RelayCommand((parameter) => CurrentView = (UserControl)Activator.CreateInstance(parameter as Type));
}
private UserControl _currentView;
public UserControl CurrentView
{
get
{
return _currentView;
}
set
{
if (value != _currentView)
{
_currentView = value;
OnPropertyChanged("CurrentView");
}
}
}
}
Я использую RelayCommand вместо DelegateCommand, но я думаю, что он работает одинаково. Команда выполняется, когда я нажимаю кнопки, а строка параметров типа - в порядке, но я получаю эту ошибку:
Перевод: Значение не может быть нулевым. Имя параметра: тип. Предложение использовать Новое ключевое слово для создания экземпляра объекта Я не знаю, где поставить ключевое слово New. Я попробовал CommandParameter, но он не будет работать. Есть идеи? Благодаря
ОБНОВЛЕНИЕ 3
После всех советов и помощи, полученных здесь, и большой работы, вот мое окончательное меню навигации и база для моего интерфейса приложения.