用数据绑定设置一个简单的组件 [英] setting up a simple component with data binding

查看:111
本文介绍了用数据绑定设置一个简单的组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设置一个具有数据绑定的组件.这基本上是一个单独的内容视图,该视图具有类型为Item的属性Item并支持绑定.以下是绑定的定义:

I am trying to set up a component with data binding. This is basically a seperate content view that would have a property Item of type Item and supports binding. The following is the definition for the binding:

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

The item doesn't seem to get bound. The commented line had a breakpoint and doesn't break. The complete source code is here: https://github.com/neville-nazerane/xamarin-component-sample

以上代码可在ItemComponent类中找到.在MainPage类中调用此组件.

The above code can be found in the ItemComponent class. This component is called in the MainPage class.

更新

仅说明我要模拟的内容以及原因:

Just to explain what I am trying to simulate and why:

为什么我们在页面中使用MVVM?虽然我们可以直接使用后面的代码来提供更好的类型安全性和性能,但是当页面的逻辑变得更大时,使用视图模型来处理它并拥有一个简单地绑定到视图的视图将变得更加干净.

Why do we use MVVM in pages? While we'll have better type safety and performance by using the behind code directly, when the page's logic gets bigger, it becomes cleaner to handle it with a view model and to have a view that is simply bound to it.

为什么要有组件?这样我们就可以重用我们打算与某些功能一起使用的UI.如果此功能变得复杂,则出于与上述相同的原因,可能需要视图模型.因此,如果页面需要视图模型,我不明白为什么组件在某些时候也不需要它们.

Why do we have components? So that we can reuse a UI we intend to use with some functionality. If this functionality becomes complex it might need a view model for the same reason explained above. Hence, if pages need view models, I don't see why components won't need them at some point too.

这被认为确实像是粒子要求,但不容易找到示例.

This being considered this does feel like a particle requirement without easy to find examples.

推荐答案

因此,在看完您的示例后,发现它确实是一个复杂的问题.因此,如果我的解释不清楚,请告诉我.

So after looking at your example it turns out it's a bit of a complicated problem. So if my explanation is not clear, please let me know.

基本上,问题出在以下两个代码段中:

Basically the problem lies in these 2 code pieces:

MainPage.xaml(第14行):

MainPage.xaml(line 14):

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

ItemComponent.xaml.cs(第43行):

ItemComponent.xaml.cs (line 43):

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

您告诉它的第一部分绑定到Demo属性,通常,它在BindingContext中查找该属性.但是,在第二部分中,您将其覆盖为BindigContext并将其设置为ItemComponentViewModel,但此ViewModel没有属性Demo,因此{Binding Demo}不适用于您设置的新BindingContext.

The first part you tell it to bind to the Demo property, and as normal it looks for this property in it's BindingContext. However in the second part you override it's BindigContext and set it to a ItemComponentViewModel this ViewModel however does not have a property Demo so the {Binding Demo} does not work on this new BindingContext you've set.

现在,您的演示应用程序可能的解决方案是将MainPage.xaml更改为以下代码:

Now a possible solution for your demo application would be to change MainPage.xaml to the following code:

<?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绑定放置在ItemComponent控件的BindingContext之外.但是,如果您想在ListView中使用它(如果我从最初的问题中正确记住,此解决方案可能无法正常工作,并且可能必须删除ItemComponentViewModel并直接绑定到属性(ListView已经确保将ItemComponent的BindingContext设置为当前Item,而无需通过可绑定的属性来传递它.

Basically we now place the Demo binding outside of the BindingContext of our ItemComponent control. However if you want to use it in a ListView (if I remember correctly from your original question, this solution might not work and it's possible you'll have to drop the ItemComponentViewModel and bind directly to the properties (ListView will already make sure that the BindingContext of your ItemComponent is set to the current Item, no need to pass it around through a bindable property.

希望这会有所帮助!

这篇关于用数据绑定设置一个简单的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆