自定义Xamarin表单控件的数据绑定失败,但适用于正常的控件

时间:2018-03-01 19:16:39

标签: c# mvvm data-binding xamarin.forms custom-controls

我有一个简单的自定义控件,我在我的Xamarin表单应用程序中使用ContentPage(实际上是一个LoginPage)。自定义控件有一个名为EntryText的属性,我尝试将其绑定到LoginViewModel的{​​{1}}属性。

如果我将Email与自定义控件Email绑定,则它似乎无效。但是,如果我将EntryText绑定到Email Entry这样的普通控件,它就能正常工作。我在这里做错了什么?

我的自定义控件:

Text

我尝试绑定的View(LoginPage)如下所示:

public class FlakeEntry2 : StackLayout
{
    public Entry Entry;
    public Label ErrorLabel;

    public FlakeEntry2()
    {
        Entry = new Entry { };
        Children.Add(Entry);

        ErrorLabel = new Label
        {
            FontAttributes = FontAttributes.Italic,
            TextColor = Color.Red,
        };
        Children.Add(ErrorLabel);
    }

    #region Text property which I am trying to bind

    public static readonly BindableProperty EntryTextProperty = BindableProperty.Create(
                                                   propertyName: nameof(EntryText),
                                                   returnType: typeof(string),
                                                   declaringType: typeof(FlakeEntry2),
                                                   defaultValue: null,
                                                   defaultBindingMode: BindingMode.TwoWay,
                                                   propertyChanged: EntryTextPropertyChanged);

    public string EntryText
    {
        get { return GetValue(EntryTextProperty)?.ToString(); }
        set { SetValue(EntryTextProperty, value); }
    }

    private static void EntryTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = (FlakeEntry2)bindable;
        control.Entry.Text = newValue?.ToString();
    }

    #endregion
}

最后,ViewModel非常标准并实现了<StackLayout Orientation="Vertical" Spacing="10"> <custom:FlakeEntry2 x:Name="Email" EntryText="{Binding Email}" /> <!--This does not work--> <Entry Text="{Binding Email}"/> <!--This works--> </StackLayout> 。其INotifyPropertyChanged属性如下:

Email

我尝试添加基于XAML的自定义控件(当前的一个只是基于C#)。 我已尝试将private string _email; public string Email { get { return _email; } set { _email = value; NotifyPropertyChanged(); } } 明确添加到BindingContext={Binding}中使用的自定义控件。 我读了很多博客,但无济于事。有人可以指点我正确的方向吗?

1 个答案:

答案 0 :(得分:3)

我听说WPF和XF绑定之间有一些不同甚至是它的XAML语法,但我对WPF知之甚少。

无论。

如何使用级联绑定并控制组件,避免暴露其内部视图?

我总是使用这种方法,对我来说效果很好,看看它是否适合你:

public class FlakeEntry2 : StackLayout
{
    private Entry Entry;
    private Label ErrorLabel;

    public FlakeEntry2()
    {
        Entry = new Entry { };

        ErrorLabel = new Label
        {
            FontAttributes = FontAttributes.Italic,
            TextColor = Color.Red,
        };

        this.Entry.SetBinding(Entry.TextProperty, new Binding(nameof(EntryText), source: this));
        // You'll need to do the same to label's and other properties you need expose, but you get rid of the 'OnChanged' methods

        Children.Add(Entry);
        Children.Add(ErrorLabel);
    }

    #region Text property which I am trying to bind

    public static readonly BindableProperty EntryTextProperty = BindableProperty.Create(
                                                   propertyName: nameof(EntryText),
                                                   returnType: typeof(string),
                                                   declaringType: typeof(FlakeEntry2),
                                                   defaultValue: null,
                                                   defaultBindingMode: BindingMode.TwoWay);
    public string EntryText
    {
        get { return GetValue(EntryTextProperty)?.ToString(); }
        set { SetValue(EntryTextProperty, value); }
    }

    #endregion
}

不应更改XAML和VM上的任何内容。