WPF usercontrol mvvm

#c# #wpf #mvvm

#c# #wpf #mvvm

Вопрос:

У меня проблема с реализацией MVVM с помощью usercontrols.

У меня есть приложение на основе MVVM.

В одном из представлений (которое является usercontrol) Слева у меня есть меню, а справа — содержимое. Содержимое меняется в зависимости от меню. Я пытался реализовать MVVM с помощью usercontrol, но я не знаю как.

Вот что я пробовал, но это не сработало :

 <UserControl x:Class="PoS.Views.OptionsView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:local="clr-namespace:PoS.Views"
    mc:Ignorable="d" 
    d:DesignHeight="450" d:DesignWidth="800">

    <UserControl.Resources>
        <DataTemplate x:Name="SettingsTemplate" DataType="{x:Type viewmodels:SettingsViewModel}">
            <views:SettingsView DataContext="{Binding}" />
        </DataTemplate>
    </UserControl.Resources>
    <Grid>

    </Grid>
</UserControl>
  

Ответ №1:

Я буду честен, я думаю, вам нужно немного перемотать назад и прочитать хорошую книгу о MVVM, прежде чем продолжить. Книга Гэри Маклина Холла Pro WPF and Silverlight MVVM — хорошее место для начала.

Чтобы ответить на ваш вопрос, я предположу, что этот пользовательский элемент управления настроен так, что его DataContext указывает на ваш MainViewModel . Для содержимого справа требуется соответствующее свойство в модели основного представления, т. Е. что-то вроде этого:

 private ViewModelBase _CurrentPage;
public ViewModelBase CurrentPage
{
    get { return this._CurrentPage; }
    set
    {
        if (this._CurrentPage != value)
        {
            this._CurrentPage = value;
            RaisePropertyChanged(() => this.CurrentPage);
        }
    }
}
  

Затем вы создаете кучу «страниц» или чего-то, что наследуется, ViewModelBase то есть Page1ViewModel , Page2ViewModel , SettingsViewModel и т.д. Затем вы создаете ContentControl и привязываете его содержимое к этому свойству:

 <ContentControl Content="{Binding CurrentPage}" />
  

Итак, теперь, если ваша модель представления выполняет что-то подобное, CurrentPage = new SettingsViewModel() тогда ContentControl будет заполнено тем, что вы объявили в качестве DataTemplate для этого типа (т. Е. элементом управления типом views:SettingsView ). Если вы присвоите свойство чему-то другому, то SettingsView оно будет уничтожено и заменено тем, чем является DataTemplate для нового типа.

В вашем примере выше будут работать только SettingsViewModel / SettingsView, потому что это все, для чего вы создали DataTemplate; чтобы это работало, вам нужно создать отдельный DataTemplate для каждого типа ViewModel / View pair, который вы создаете.

Комментарии:

1. Меня заинтересовала рекомендованная вами книга «Pro WPF и Silverlight MVVM», но отзывы о ней на Amazon невелики. Если вы не возражаете, я хотел бы знать, почему вы считаете, что это хорошая книга.

2. Честно? Потому что это тот, на котором я изначально учился, и в то время я нашел его очень поучительным. Конечно, это было около 7 или 8 лет назад, о чем свидетельствует тот факт, что в его названии есть «Silverlight», так что, возможно, сейчас есть просто много гораздо лучших вариантов. Я также обнаружил, что «Продвинутый MVVM» Джоша Смита заслуживает прочтения и содержит несколько хороших практических советов, хотя и немного вкратце.