настройка простого компонента с привязкой данных - PullRequest
0 голосов
/ 03 марта 2019

Я пытаюсь настроить компонент с привязкой данных.Это в основном отдельное представление содержимого, которое будет иметь свойство Item типа Item и поддерживает привязку.Ниже приведено определение привязки:

public static readonly BindableProperty ItemProperty
    = BindableProperty.Create(
                nameof(Item), typeof(Item), typeof(ItemComponent), null,
                defaultBindingMode: BindingMode.TwoWay,
                propertyChanged: ItemPropertyChanged);
private readonly ItemComponentViewModel vm;

static void ItemPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
    var view = (ItemComponent)bindable;
    view.Item = (Item)newValue;
}

public Item Item
{
    get => (Item)GetValue(ItemProperty);
    set
    {
        SetValue(ItemProperty, value);
        if (vm != null) vm.Data = value; // break point here
    }
}

Элемент, похоже, не привязан.Комментируемая строка имеет точку останова и не прерывается.Полный исходный код находится здесь: https://github.com/neville-nazerane/xamarin-component-sample

Приведенный выше код можно найти в классе ItemComponent.Этот компонент вызывается в классе MainPage.

Обновление

Просто чтобы объяснить, что я пытаюсь смоделировать и почему:

Почему мы используем MVVM на страницах?В то время как у нас будет больше безопасности и производительности при использовании прямого кода, но когда логика страницы станет больше, станет проще обрабатывать ее с помощью модели представления и иметь представление, которое просто связано с ним.

Почему у нас есть компоненты?Чтобы мы могли повторно использовать пользовательский интерфейс, который мы собираемся использовать с некоторыми функциями.Если эта функциональность усложняется, ей может потребоваться модель представления по той же причине, что и описанная выше.Следовательно, если страницам нужны модели просмотра, я не понимаю, почему компонентам они тоже не нужны.

Учитывая это, это похоже на требование к частице без простых примеров.

1 Ответ

0 голосов
/ 03 марта 2019

Итак, после просмотра вашего примера выясняется, что это немного сложная проблема.Так что, если мое объяснение не ясно, пожалуйста, дайте мне знать.

В основном проблема заключается в следующих двух частях кода:

MainPage.xaml (строка 14):

<local:ItemComponent Item="{Binding Demo}" />

ItemComponent.xaml.cs (строка 43):

public ItemComponent()
{
    InitializeComponent();
    vm = new ItemComponentViewModel();
    BindingContext = vm; //this breaks the functionality
}

Первая часть, в которой вы говорите, чтобы она связывалась со свойством Demo, и, как обычно, ищет это свойство в своем BindingContext.Однако во второй части вы переопределяете его BindigContext и устанавливаете для него ItemComponentViewModel этот ViewModel, однако, не имеет свойства Demo, поэтому {Binding Demo} не работает на этом новом установленном вами BindingContext.

Теперь возможным решением для вашего демонстрационного приложения было бы изменить MainPage.xaml на следующий код:

<?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:local="clr-namespace:SampleApp"
             x:Class="SampleApp.MainPage"
             x:DataType="local:MainViewModel"
             x:Name="MyDemoPage">
    <StackLayout>
        <Label Text="Manual:" />
        <Label Text="{Binding Demo.Title}" />
        <Label Text="Component: " />
        <local:ItemComponent Item="{Binding Path=BindingContext.Demo, Source={x:Reference MyDemoPage}}" />
    </StackLayout>
</ContentPage>

По сути, теперь мы помещаем привязку Demo вне BindingContext нашего ItemComponent элемента управления.Однако, если вы хотите использовать его в ListView (если я правильно помню из вашего исходного вопроса, это решение может не сработать, и возможно, вам придется отбросить ItemComponentViewModel и привязать непосредственно к свойствам (ListView уже убедится, чточто BindingContext вашего ItemComponent установлен на текущий Item, нет необходимости передавать его через связываемое свойство.

Надеюсь, это поможет!

...