Xamarin表单可绑定属性条目不起作用



我正在构建一个具有可绑定属性的位,并且在输入新文本时不会触发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";
}
}

最新更新