Пользовательский элемент управления Xamarin.Forms BindingContext не работает внутри DataTemplate? - PullRequest
0 голосов
/ 02 февраля 2020

Я пытаюсь использовать BindableLayout со StackLayout для отображения элементов из коллекции, но по какой-то причине привязки не работают при использовании BindableLayout. Во время отладки с горячей перезагрузкой XAML он иногда начинает работать после перезагрузки, но не работает после обновления пользовательского интерфейса.

Репозиторий здесь , если необходимо, но это рассматриваемый код:

Example Image

Страница XAML: (пользовательский элемент управления ComicInfoView)

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         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"
         xmlns:pages="clr-namespace:ComicBud.Pages"
         xmlns:views="clr-namespace:ComicBud.Views"
         mc:Ignorable="d"
         x:Class="ComicBud.Pages.HomePage"
         Title="ComicBud">

<ContentPage.ToolbarItems>
    <ToolbarItem IconImageSource="ic_add_white_36dp" Command="{Binding AddComicUrlCommand}" />
</ContentPage.ToolbarItems>

<ContentPage.Resources>
    <x:String x:Key="pageBorder">10</x:String>
</ContentPage.Resources>

<ContentPage.Content>
    <RefreshView IsRefreshing="{Binding IsRefreshing}"
                 Command="{Binding RefreshCommand}">
        <ScrollView Orientation="Vertical">
            <StackLayout Margin="0, 10, 0, 10">

                <StackLayout Orientation="Vertical"
                             IsVisible="{Binding IsAnyComics}">
                    <Label Text="Using BindableLayout"
                           FontSize="Subtitle"
                           Margin="10, 0, 10, 0"/>
                    <ScrollView Orientation="Horizontal"
                                HorizontalScrollBarVisibility="Never">
                        <StackLayout Orientation="Horizontal"
                                     Spacing="10"
                                     Padding="10, 5, 10, 5"
                                     BindableLayout.ItemsSource="{Binding Comics}">
                            <BindableLayout.ItemTemplate>
                                <DataTemplate>
                                    <views:ComicInfoView />
                                </DataTemplate>
                            </BindableLayout.ItemTemplate>
                        </StackLayout>
                    </ScrollView>
                </StackLayout>

                <StackLayout Orientation="Vertical"
                             IsVisible="{Binding IsAnyComics}">
                    <Label Text="Manual"
                           FontSize="Subtitle"
                           Margin="10, 0, 10, 0"/>
                    <ScrollView Orientation="Horizontal"
                                HorizontalScrollBarVisibility="Never">
                        <StackLayout Orientation="Horizontal"
                                     Spacing="10"
                                     Padding="10, 5, 10, 5">
                            <views:ComicInfoView />
                        </StackLayout>
                    </ScrollView>
                </StackLayout>

            </StackLayout>
        </ScrollView>
    </RefreshView>
</ContentPage.Content>

ComicInfoView .xaml:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
         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"
         xmlns:views="clr-namespace:ComicBud.Views"
         mc:Ignorable="d"
         x:Class="ComicBud.Views.ComicInfoView">

<ContentView.BindingContext>
    <views:ComicInfoViewModel />
</ContentView.BindingContext>

<ContentView.Content>
    <StackLayout Orientation="Horizontal">
        <Frame WidthRequest="60"
               HeightRequest="84"/>
        <StackLayout RelativeLayout.XConstraint=
                            "{ConstraintExpression Type=RelativeToParent,
                                                   Property=Width,
                                                   Factor=0,
                                                   Constant=100}"
                     Margin="0, 5, 10, 0"
                     Spacing="0">
            <Label Text="{Binding ComicName}"
                   HorizontalTextAlignment="Start"
                   FontSize="Subtitle"
                   LineBreakMode="WordWrap"
                   WidthRequest="100"/>
            <Label Text="Last Read"
                   HorizontalTextAlignment="Start"
                   FontSize="Micro"
                   Margin="0, 5, 0, 0"/>
            <Label Text="3 days ago"
                   HorizontalTextAlignment="Start"
                   FontSize="Small"/>
            <Label Text="Updated"
                   HorizontalTextAlignment="Start"
                   FontSize="Micro"
                   Margin="0, 5, 0, 0"/>
            <Label Text="2 days ago"
                   HorizontalTextAlignment="Start"
                   FontSize="Small"/>
        </StackLayout>

        <StackLayout.GestureRecognizers>
            <TapGestureRecognizer Command="{Binding OpenComicCommand}"/>
        </StackLayout.GestureRecognizers>

    </StackLayout>
</ContentView.Content>

ComicInfoViewModel.cs

using System.ComponentModel;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using FreshMvvm;
using ComicBud.Pages;
using ComicBud.Systems;

namespace ComicBud.Views
{
public class ComicInfoViewModel : INotifyPropertyChanged
{
    public ComicInfoViewModel()
    {
        OpenComicCommand = new Command(async () => await OpenComic());
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private Comic _comic;

    public Comic Comic
    {
        get { return _comic; }
        set
        {
            _comic = value;

            OnPropertyChanged();
            OnPropertyChanged(nameof(ComicName));
        }
    }

    public string ComicName
    {
        get { return "Binding Is Working"; }
    }

    public Command OpenComicCommand { get; }

    private async Task OpenComic()
    {
        var navService = FreshIOC.Container.Resolve<IFreshNavigationService>(Constants.DefaultNavigationServiceName);
        var page = FreshPageModelResolver.ResolvePageModel<ComicDetailPageModel>();
        await navService.PushPage(page, null);
    }

    private void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
}

РЕДАКТИРОВАТЬ: оборачивать ComicInfoView в шаблон данных с чем-то (Frame, ContentView и т. д. c) кажется, это исправить. Вот так:

<BindableLayout.ItemTemplate>
     <DataTemplate>
           <ContentView>
                 <views:ComicInfoView/>
           </ContentView>
     </DataTemplate>
</BindableLayout.ItemTemplate>

Я отмечу вопрос как решенный, но если кто-нибудь сможет пролить свет на то, почему это так, то это будет оценено!

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