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));
            }
        }
    }

请在自定义控件的代码中进行绑定,并在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";
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...