问题描述
我在使用可绑定属性和输入新文本时没有触发 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));
}
}
}
请在自定义控件的代码中进行绑定,并在viewmodel中对绑定属性进行属性更改。
CustomEntry.SetBinding(Entry.TextProperty,source: this));
OnPropertyChange(nameof(TitleText));
请参考https://www.youtube.com/watch?v=ZViJyL9Ptqg。
我已测试此代码能够在从自定义视图更改条目文本时触发 propertyChanged 事件。
,它绑定了“绑定”值就好了,但是在条目中输入的后续更改不会引发属性更改。
From Bindable Properties property changes,BindableProperty MyEntryTextProperty 绑定TextPropertyFromBindingContext,所以当你改变TextPropertyFromBindingContext 时会触发propertyChanged 事件,而不是改变MyEntry 的值。
您可以更改 TextPropertyFromBindingContext bu Button.click,然后您将看到 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";
}
}