我有一个简单的自定义控件,我在 ContentPage
中使用它(实际上是一个 LoginPage)在我的 Xamarin 表单应用程序中。自定义控件有一个名为 EntryText
的属性。我试图绑定(bind)到 LoginViewModel
的Email
属性(property)。
如果我绑定(bind)Email
使用自定义控件的 EntryText
,它似乎不起作用。但是,如果我绑定(bind) 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
}
我尝试绑定(bind)的 View (LoginPage)如下所示:
<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
. Email
其属性如下所示:private string _email;
public string Email
{
get { return _email; }
set
{
_email = value;
NotifyPropertyChanged();
}
}
我尝试添加一个基于 XAML 的自定义控件(当前一个只是基于 C#)。
我已尝试明确添加
BindingContext={Binding}
到 LoginPage
中使用的自定义控件.我阅读了许多博客,但无济于事。有人可以指出我正确的方向吗?
最佳答案
我听说 WPF 和 XF 绑定(bind)甚至它的 XAML 语法之间有些不同,但我对 WPF 知之甚少。
任何。
如何使用级联绑定(bind)并控制您的组件避免暴露其内部 View ?
我总是使用这种方法并且对我来说效果很好,看看它是否也适合你:
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 上的任何内容都不应更改。
关于c# - 自定义 Xamarin 表单控件的数据绑定(bind)失败,但适用于普通控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49057135/