我正在构建一个具有可绑定属性的位,并且在输入新文本时不会触发propertyChanged事件。
我做了一个最小的代码样本:
Xaml自定义控制:
<Grid xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BindingPropertyProject.CustomFlyout">
<Entry x:Name="MyEntry"/>
编码背后:
public partial class CustomFlyout : Grid
{
public CustomFlyout()
{
InitializeComponent();
}
public string MyEntryText
{
get { return (string)GetValue(MyEntryTextProperty); }
set
{
SetValue(MyEntryTextProperty, value);
}
}
public static readonly BindableProperty MyEntryTextProperty =
BindableProperty.Create(nameof(MyEntryText), typeof(string),
typeof(CustomFlyout),
defaultValue: string.Empty,
defaultBindingMode: BindingMode.TwoWay
, propertyChanging: TextChanged);
private static void TextChanged(BindableObject bindable, object oldValue, object newValue)
{
if (bindable is CustomFlyout control)
{
control.MyEntry.Text = newValue?.ToString();
}
}
}
}
消费类xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:BindingPropertyProject"
x:Class="BindingPropertyProject.MainPage">
<Grid>
<local:CustomFlyout MyEntryText="{Binding TextPropertyFromBindingContext, Mode=TwoWay}" HorizontalOptions="FillAndExpand" VerticalOptions="Start"/>
</Grid>
消费类代码隐藏:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = this;
}
private string _textPropertyFromBindingContext = "bound";
public string TextPropertyFromBindingContext
{
get
{
return _textPropertyFromBindingContext;
}
set
{
if (_textPropertyFromBindingContext != value)
{
_textPropertyFromBindingContext = value;
OnPropertyChanged();
}
}
}
}
它将";绑定";值很好,但在条目中输入的后续更改不会引发属性更改。
我试了很多从谷歌上找到的建议,但这应该没问题,对吧?
更新:好的,所以我实际上通过在自定义视图中添加绑定来工作:
<Grid xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BindingPropertyProject.CustomFlyout">
<Entry x:Name="MyEntry" Text="{Binding TextPropertyFromBindingContext }"/>
这真的是办法吗?我的意思是,我只能让它工作,如果绑定在自定义视图中的名称完全相同,并且使用部分。。
我只能让它工作,如果绑定在自定义视图和消费部件。。
不需要具有相同的绑定名称。请参阅以下代码。
自定义控制
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StackQA2XF.CustomControl.MyCustomControl">
<ContentView.Content>
<Entry x:Name="CustomEntry"/>
</ContentView.Content>
</ContentView>
public partial class MyCustomControl : ContentView
{
public static readonly BindableProperty EntryTextProperty =
BindableProperty.Create(nameof(EntryText), typeof(string), typeof(MyCustomControl), default(string), BindingMode.TwoWay);
public string EntryText
{
get { return (string)GetValue(EntryTextProperty); }
set { SetValue(EntryTextProperty, value); }
}
public MyCustomControl()
{
InitializeComponent();
CustomEntry.SetBinding(Entry.TextProperty, new Binding(nameof(EntryText), source: this));
}
}
消费类
<customcontrols:MyCustomControl EntryText="{Binding TitleText}"/>
public class MainViewModel : INotifyPropertyChanged
{
private string _titleText = "Good morning";
public string TitleText
{
get
{
return _titleText;
}
set
{
_titleText = value;
OnPropertyChange(nameof(TitleText));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChange(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
请在自定义控件的代码中执行绑定,并引发视图模型中绑定属性的属性更改。
CustomEntry.SetBinding(Entry.TextProperty,new Binding(名称为(EntryText(,源:this((;
OnPropertyChange(名称为(TitleText((;
请参阅https://www.youtube.com/watch?v=ZViJyL9Ptqg.
我已经测试了这段代码,当从自定义视图更改Entry文本时,它能够获得激发的propertyChanged事件。
它绑定了"绑定";值很好,但在条目中输入的后续更改不会引发属性更改。
从BindableProperties属性更改,BindablePropertyMyEntryTextProperty绑定TextPropertyFromBindingContext,因此当您更改TextPropertyFrombindContext时将触发propertyChanged事件,而不是更改MyEntry的值。
您可以通过按钮更改TextPropertyFromBindingContext,然后您将看到propertyChanged事件将被触发。
public partial class Page3 : ContentPage, INotifyPropertyChanged
{
private string _textPropertyFromBindingContext = "bound";
public string TextPropertyFromBindingContext
{
get
{
return _textPropertyFromBindingContext;
}
set
{
if (_textPropertyFromBindingContext != value)
{
_textPropertyFromBindingContext = value;
RaisePropertyChanged("TextPropertyFromBindingContext");
}
}
}
public Page3()
{
InitializeComponent();
this.BindingContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
private void btn1_Clicked(object sender, EventArgs e)
{
TextPropertyFromBindingContext = "test";
}
}