我有一个简单的自定义控件,我在我的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}
中使用的自定义控件。
我读了很多博客,但无济于事。有人可以指点我正确的方向吗?
答案 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上的任何内容。