Prism с Xamarin.Forms - как автоматически связать ContentView, который находится внутри другого ContentView - PullRequest
0 голосов
/ 29 апреля 2020

Мы успешно подключаем ContentViews к их ViewModel, когда ContentView непосредственно содержится на странице, используя XAML, например:

<local:AwesomeView mvvm:ViewModelLocator.AutowirePartialView=”{x:Reference self}” />

Где self - родительская страница.

Однако у нас есть ContentViews, которые содержат ContentViews, и использование AutoWirePartialView , как указано выше, для вложенного представления не работает. ContentViews не подключаются к своим ViewModels.

Просмотр кода Prism:

  1. AutoWirePartialView содержит комментарий "Этот API устарел и будет удален во время предварительный просмотр 8.0 "
  2. Обработчик изменения свойства для AutoWirePartialView явно проверяет, является ли родительский элемент Page , поэтому не будет работать с родительским ContentView

Так что из кода Prism довольно ясно, почему это не сработает!

Есть ли способ достичь этого с помощью Prism?

Версии: Xamarin.Forms - 4.4.0.991265

Prism - 7.1.0.431

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

Мое мнение, чтобы сохранить чистоту, состоит в том, чтобы использовать подход призмы по умолчанию и привязать модель представления только к соответствующей странице, а не к каким-либо подпредставлениям.

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

Например:

Модель представления вашей страницы

public class PageAViewModel : ViewModelBase
{
   public ContentViewAViewModel ContentViewViewModel
   {
      get { return _contentViewViewModel; }
      set { SetProperty(ref _contentViewViewModel, value); }
   }
}

Просмотр вашей страницы

<?xml version="1.0" encoding="UTF-8"?>
<views:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
                xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                xmlns:components="clr-YourProject.Components"
                xmlns:views="clr-YourProject.Views"
                x:Class="YourProject.Views.PageA">
     <Grid RowSpacing="0">
          <Grid RowSpacing="0">
                <components:ContentViewA BindingContext="{Binding ContentViewViewModel}"/>
          </Grid>
    </Grid>
</views:BasePage>
0 голосов
/ 29 апреля 2020

Частичные представления действительно делаются устаревшими. Причина, по которой он устарел, заключается в том, что мы привносим Поддержка регионов в Prism 8. Частичные представления всегда предназначались как быстрое и временное решение, помогающее сократить разрыв до тех пор, пока мы не приступим к реализации Regions for Prism.Forms. Регионы гораздо более мощные и позволят вам сделать гораздо больше, например, вложения и ленивую загрузку представлений.

Реально концепция вложенных регионов, в которой вы имеете:

ComponentViewA, который имеет свои собственный ViewModel.

Тогда у вас есть ComponentViewB, который имеет собственный ViewModel и имеет ComponentViewA как дочерний элемент

, а ComponentViewA сам является дочерним по отношению к AwesomePage

Похоже, это общая концепция, которую вы хотите поддержать. Таким образом, короткий ответ заключается в том, что в Prism 7 нет хорошего способа сделать это. Конечно, есть некоторые хаки, которые вы могли бы, например, передать на страницу в качестве параметра и установить свойство в коде, например:

public class ComponentViewB : ContentView
{
    public static readonly BindableProperty ParentPageProperty =
        BindableProperty.Create(nameof(ParentPage), typeof(Page), typeof(ComponentViewB), null, propertyChanged: OnParentPageChanged);

    private static void OnParentPageChanged(BindableObject bindable, object oldValue, object newValue)
    {
        // This guards the action from being performed more than once.
        if(oldValue is null && newValue != null && bindable is ComponentViewB view)
        {
            // This assumes you've set the property x:Name="componentViewA"
            // for your ComponentViewA in XAML
            ViewModelLocator.SetAutowirePartialView(view.componentViewA, (view.ParentPage);
        }
    }

    public Page ParentPage
    {
        get => (Page)GetValue(ParentPageProperty);
        set => SetValue(ParentPageProperty, value);
    }
}

Если честно, если бы я сегодня заставил что-то работать, вот как я рекомендовал бы сделать это. После слияния PR, на который я ссылался выше, я бы предложил вам обновить предварительный просмотр и перейти на использование регионов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...