代码之家  ›  专栏  ›  技术社区  ›  bit

自定义Xamarin表单控件的数据绑定失败,但对普通控件有效

  •  0
  • bit  · 技术社区  · 6 年前

    我有一个简单的自定义控件,我在 ContentPage (实际上是登录页面)在我的Xamarin表单应用程序中。自定义控件有一个名为 EntryText 我正试图将其绑定到 LoginViewModel Email 所有物

    如果我绑定 电子邮件 使用自定义控件的 入口文本 ,它似乎不起作用。但是,如果我绑定 电子邮件 到正常控件,如 Entry Text ,它确实工作正常。我做错了什么?

    我的自定义控件:

    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
    }
    

    我尝试绑定的视图(登录页面)如下所示:

    <StackLayout Orientation="Vertical" Spacing="10">
        <custom:FlakeEntry2 x:Name="Email" EntryText="{Binding Email}" /> <!--This does not work-->
        <Entry Text="{Binding Email}"/> <!--This works-->
    </StackLayout>
    

    最后,ViewModel几乎是标准的并实现了 INotifyPropertyChanged . 这个 电子邮件 其属性如下所示:

    private string _email;
    public string Email
    {
        get { return _email; }
        set
        {
            _email = value;
            NotifyPropertyChanged();
        }
    }
    

    我尝试添加一个基于XAML的自定义控件(当前的控件只是基于C的)。 我已尝试明确添加 BindingContext={Binding} 中使用的自定义控件 LoginPage . 我读了很多博客,但都没有用。有人能给我指一下正确的方向吗?

    1 回复  |  直到 6 年前
        1
  •  4
  •   Diego Rafael Souza    6 年前

    我听说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上的任何内容。