Является ли создание экземпляров класса в VM, совместимым с MVVM? Как еще если так? - PullRequest
0 голосов
/ 07 мая 2018

У меня есть страница содержимого и ContentView со свойством содержимого, связанным с моделью представления

MainPage: `

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="MvvM.Views.MainPage"
             xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MvvM.Views"
             xmlns:vm="clr-namespace:MvvM.ViewModels">
  <!--  ViewModel BindingContext  -->
  <ContentPage.BindingContext>
    <vm:MainViewModel />
  </ContentPage.BindingContext>

  <Grid>
    <Grid.RowDefinitions>
      <!--  Header Row  -->
      <RowDefinition Height="50" />
      <!--  ContentView Row  -->
      <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <!--  Header  -->
    <Grid Grid.Row="0"
          BackgroundColor="CornflowerBlue"
          VerticalOptions="FillAndExpand">
      <!--  Button On Header  -->
      <Button Command=""
              Text="Page Switch"
              VerticalOptions="Center">
        <Button.GestureRecognizers>
          <TapGestureRecognizer Command="TapGestureCommand" />
        </Button.GestureRecognizers>
      </Button>
    </Grid>

    <!--  Content Container  -->
    <Grid Grid.Row="1" VerticalOptions="Center">
      <ContentView Content="{Binding DisplayPage}" />
    </Grid>

  </Grid>

</ContentPage>

`

ViewModel:

`using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Runtime.CompilerServices;
 using System.Text;
 using MvvM.Views;
 using Xamarin.Forms;

namespace MvvM.ViewModels
{
    public class MainViewModel :INotifyPropertyChanged
    {
        public MainViewModel()
        {
            DisplayPage = new Views.MainPage();
        }

        private ContentPage _displayPage;
        public ContentPage DisplayPage
        {
            get { return _displayPage; }
            set 
            {
                if (value != _displayPage)
                {
                    _displayPage = value;
                }
            }

        }



        private ContentView _contentToDisplayView;

        public ContentView SelectedView
        {
            get => _contentToDisplayView;
            set
            {
                _contentToDisplayView = value;
                OnPropertyChanged();
            } 
        }

        public Command TapGestureCommand
        {
            get
            {
                return new Command(TapGesture);

            }
        }

        private void TapGesture()
        {
            _contentToDisplayView = new RedView();
            _displayPage.Content = _contentToDisplayView.Content;
            OnPropertyChanged();
        }

        #region PropertyChangedHandler
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
#endregion
    }
}`

и вторая страница под названием «RedPage» хочет получить доступ к содержимому с

`

<?xml version="1.0" encoding="utf-8" ?>
<ContentView x:Class="MvvM.Views.RedView"
             xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:MvvM.ViewModels"
             BindingContext="vm:MainViewModel">
  <ContentView.Content>
    <Grid Width="*"
          Height="*"
          BackgroundColor="Red" />
  </ContentView.Content>
</ContentView> `

В результате я хочу получить содержимое ContentView на RedPage, которое будет отображаться в представлении содержимого главной страницы.

  • создает экземпляр красной страницы в модели представления MVVM жалоба? (Я чувствую, что это сильно связывает вид с моделью?)

    • как еще я могу получить свойство контента на красной странице в модель представления? (Не могу связать его и установить элементы в нем, так как вы можете установить свойство контента только один раз)

1 Ответ

0 голосов
/ 07 мая 2018

В идеале вы бы хотели, чтобы ViewModel ничего не знала о представлении, и наоборот, поэтому с этой точки зрения это не то, что вы хотели бы.

Чтобы преодолеть это, вам нужна навигация ViewModel-ViewModel. Таким образом, вы просто указываете, к какой ViewModel вы хотите перейти, и соответствующий View будет загружен. Вы можете реализовать это вручную, и в зависимости от выбранной вами реализации у вас будет какой-то способ разрешения представления, связанного с этой моделью представления.

Один из способов сделать это - назвать соглашения и рефлексию. Это означает, что вы называете все свои страницы как:

  • MyPage
  • YourPage
  • OurPage

И все ViewModels, такие как:

  • MyPageModel
  • YourPageModel
  • OurPageModel

Тогда с помощью отражения вы можете просто удалить суффикс "Model" и разрешить страницу оттуда. Обратите внимание, что я использую именование Page и PageModel, но, конечно, это работает и для View и ViewModel. После этого вам все равно придется учитывать навигацию к этим представлениям и обратно, модальные они или нет и т. Д.

Хотя вы можете реализовать все это вручную, вероятно, стоило бы взглянуть на инфраструктуру MVVM. Метод, который я только что описал, заключается в том, как FreshMvvm делает это, например. Но есть и другие хорошие фреймворки, такие как Prism, Exrin, MvvmCross и т. Д.

...