Как мне привязать MvxContentView к данным в DataTemplate и заставить MvvmCross загрузить ViewModel для этого?

#c# #xamarin #binding #mvvmcross

#c# #xamarin #обязательный #mvvmcross

Вопрос:

У меня есть MvxContentPage с CollectionView. Элементы в CollectionView должны быть представлены с помощью MvxContentView. Я пытался и пытался, но не могу заставить MvxContentView загружать связанную с ним ViewModel. Я загрузил код MvvmCross и просмотрел образцы. В проекте PlayGround есть пример, но он кажется неполным.

На странице ниже показано содержимое набора. Набор содержит n setItems, которые должны быть показаны в CollectionView. Каждый setItem представлен с использованием частичного представления.

Вот мой код:

Страницу mvxcontent:

 <?xml version="1.0" encoding="utf-8" ?>
<mvx:MvxContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:mvx="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
    xmlns:views="clr-namespace:eTabber.Views"
    xmlns:model="clr-namespace:eTabber.Data.Model;assembly=eTabber.Data"
    xmlns:viewmodels="clr-namespace:eTabber.Core.ViewModels;assembly=eTabber.Core"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:d="http://xamarin.com/schemas/2014/forms/design"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Padding="0"
    x:Class="eTabber.Views.SetView" x:TypeArguments="viewmodels:SetViewModel"
    Title="{Binding PageTitle}" >

    <StackLayout
        StyleClass="MainContainer"
        Spacing="0"
        Margin="0"
        Padding="0">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>
                <RowDefinition Height="auto" />
                <RowDefinition Height="auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>

            <Label Text="{Binding SetList.Name, Mode=OneWay}" StyleClass="Title" Grid.Row="0"></Label>
            <StackLayout Orientation="Vertical" Grid.Row="1">
                <Button Text="Add" Command="{Binding AddCommand}" />
                <CollectionView ItemsSource="{Binding SetItems}" 
                                HorizontalOptions="FillAndExpand"
                                VerticalOptions="FillAndExpand"
                                x:Name="SetlistsListView"
                                Grid.Row="2"
                                SelectionMode="Single"
                                ChildrenReordered="SetlistsListView_ChildrenReordered">
                    <CollectionView.ItemTemplate>
                        <DataTemplate x:DataType="model:SetItem" x:Name="DataTemplate">
                            <views:SetItemView BindingContext="{Binding Source={x:Reference DataTemplate}}" />
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </StackLayout>
        </Grid>
    </StackLayout>
</mvx:MvxContentPage>
  

И частичное представление с помощью MvxContentView:

 <?xml version="1.0" encoding="UTF-8"?>
<mvx:MvxContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:mvx="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewmodels="clr-namespace:eTabber.Core.ViewModels;assembly=eTabber.Core"
             x:TypeArguments="viewmodels:SetItemViewModel"
             x:Class="eTabber.Views.SetItemView">
    <ContentView.Content>
        <Grid x:Name="SetlistsInnerView" RowSpacing="0">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Label Text="{Binding Set.SetName, Mode=OneWay}"
                                       IsVisible="{Binding TitleVisible, Mode=OneWay}"
                                       StyleClass="Title"
                                       Grid.Row="0">
            </Label>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="2*"/>
                </Grid.ColumnDefinitions>

                <Label Text="{Binding Path=Song.Artist.Name, Mode=OneWay}" Grid.Column="0" Grid.Row="0" StyleClass="Label"/>
                <Label Text="{Binding Path=Song.Title, Mode=OneWay}" Grid.Column="1" Grid.Row="0" StyleClass="Label"/>
            </Grid>
        </Grid>
    </ContentView.Content>
</mvx:MvxContentView>
  

Код, лежащий в основе:

 using eTabber.Core.ViewModels;
using MvvmCross.Forms.Views;
using Xamarin.Forms.Xaml;

namespace eTabber.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class SetItemView : MvxContentView<SetItemViewModel>
    {
        public SetItemView()
        {
            InitializeComponent();
        }
    }
}
  

И ViewModel:

 using eTabber.Data.Model;
using MvvmCross.Navigation;
using Xamarin.Forms;

namespace eTabber.Core.ViewModels
{
    public class SetItemViewModel : BaseViewModel<SetItem>
    {
        public SetItem SetItem { get => passedEntity; set => passedEntity = value; }

        public SetItemViewModel(IMvxNavigationService navigationService) : base(navigationService)
        {
            var context = View.BindingContextProperty;
        }
    }
}
  

Он показывает страницу с информацией, поэтому происходит некоторая привязка, но я хочу, чтобы она загружала ViewModel (в этом случае привязки, конечно, должны быть разными). Вот что он отображает:

введите описание изображения здесь

Проблема заключается в первом коде MvxContentPage:

<views:SetItemView BindingContext=»{Источник привязки ={x:Эталонная табличка данных}}» />

Что мне указать в привязке, чтобы загрузить SetItemViewModel.

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

1. В вашем коде я не вижу привязки для MvxContentView . Вы пытались установить привязку в коде позади?

2. Нет, я бы хотел, чтобы это было установлено в XAML