结合自定义视图在Xamarin.Forms [英] Binding a Custom View In Xamarin.Forms

查看:184
本文介绍了结合自定义视图在Xamarin.Forms的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题在Xamarin形式,包含页面的视图模式自定义视图绑定数据。

I have a problem binding data in a custom view in Xamarin forms to the view model of the containing page.

我的自定义视图很简单,一对代表一个键值对标签:

My Custom View is very simple, a pair of labels representing a key value pair:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="KeyValueView">
    <Grid VerticalOptions="Start">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Label x:Name="KeyLabel" Text="{Binding Key}"  Grid.Column="0" HorizontalOptions="Start" />
        <Label x:Name="ValueLabel" Text="{Binding Value}" Grid.Column="1" HorizontalOptions="EndAndExpand" />
    </Grid>
</ContentView>



背后的代码:

with the code behind:

public partial class KeyValueView : ContentView
{
    public KeyValueView()
    {
        InitializeComponent();
        this.VerticalOptions = LayoutOptions.Start;
        this.BindingContext = this;
    }

    public static readonly BindableProperty ValueProperty =
                BindableProperty.Create<KeyValueView, string>(w => w.Value, default(string));

    public string Value
    {
        get {return (string)GetValue(ValueProperty);}
        set {SetValue(ValueProperty, value);}
    }

    public static readonly BindableProperty KeyProperty =
        BindableProperty.Create<KeyValueView, string>(w => w.Key, default(string));

    public string Key
    {
        get {return (string)GetValue(KeyProperty);}
        set {SetValue(KeyProperty, value);}
    }
}

这是在一个页面使用情况如下:

This is consumed in a page as follows:

<views:KeyValueView Key="Order Number" Value="{Binding document_number}" />

的问题是,按预期的方式显示密钥字符串,但字符串值是没有的。
我试图迫使PropertyChanged事件的document_number财产,这并没有帮助。
我也试图明确自定义视图的键/值属性的setter方法​​中设置标签上的Text属性:

The problem is that the Key string is displayed as expected, but the value string is not. I have tried forcing a PropertyChanged event on the document_number property, this did not help. I have also tried explicitly setting the Text property on the Labels during the setter of the Key/Value properties of the custom view:

public string Key
    {
        get {return (string)GetValue(KeyProperty);}
        set {
            SetValue(KeyProperty, value);
            KeyLabel.Text = value;
        }
    }



此外,这并没有帮助,二传手代码似乎从来没有得到执行的(我把一个断点上,它是未命中)

Again this did not help, the setter code never seems to get executed (I placed a breakpoint on it and it was not hit)

如果我增加一个开箱即用的控制,如直接绑定到属性在标签页面,这将显示正确的:

If I add an out of the box control such as a Label bound directly to the property in the page, this displays correctly:

<Label Text="{Binding document_number}"/>
<views:KeyValueView Key="Order Number" Value="{Binding document_number}" />



任何人都可以解释为什么发生这种情况(或者说没有发生)?

Can anyone explain why this is happening (or rather not happening)?

推荐答案

不要里面自定义控件内部分配绑定。使用这样的:

Don't assign bindings internally inside custom controls. Use this:

public partial class KeyValueView : ContentView
{
    public KeyValueView()
    {
        InitializeComponent();
        this.VerticalOptions = LayoutOptions.Start;
    }

    public static readonly BindableProperty ValueProperty =
        BindableProperty.Create<KeyValueView, string>(w => w.Value, default(string));

    public string Value
    {
        get {return (string)GetValue(ValueProperty);}
        set {SetValue(ValueProperty, value);}
    }

    public static readonly BindableProperty KeyProperty =
        BindableProperty.Create<KeyValueView, string>(w => w.Key, default(string));

    public string Key
    {
        get {return (string)GetValue(KeyProperty);}
        set {SetValue(KeyProperty, value);}
    }
    protected override void OnPropertyChanged(string propertyName)
    {
        base.OnPropertyChanged(propertyName);

        if (propertyName == ValueProperty.PropertyName)
        {
            ValueLabel.Text = Value;
        }
        if (propertyName == KeyProperty.PropertyName)
        {
            KeyLabel.Text = Key;
        }
    }
}

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="KeyValueView">
    <Grid VerticalOptions="Start">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Label x:Name="KeyLabel" Grid.Column="0" HorizontalOptions="Start" />
        <Label x:Name="ValueLabel" Grid.Column="1" HorizontalOptions="EndAndExpand" />
    </Grid>
</ContentView>



治疗性(例如值)为BindableProperty(ValueProperty)引用。如果你这样做的价值二传手BindableProperty里面的东西也不会对此进行通知,相反,如果你做BindableProperty(分配/更改ValueProperty)的东西 - 属性值设置器将不会被调用。

Treat properties (eg. Value) as references to BindableProperty (ValueProperty). If you do something inside Value setter BindableProperty won't be notified about it AND opposite if you do something with BindableProperty (assign/change ValueProperty) - property Value setter won't be called.

如果你想处理的PropertyChanged你有那个(OnPropertyChanged)一个覆盖或操作(如附加参数创建BindableProperty时)。

If you want to handle PropertyChanged you have an override for that (OnPropertyChanged) or Actions (as additional parameters when creating BindableProperty).

这篇关于结合自定义视图在Xamarin.Forms的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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