【问题标题】:Xamarin forms bindable property entry not workingXamarin 表单可绑定属性条目不起作用
【发布时间】:2021-03-20 07:02:27
【问题描述】:

我正在为一个可绑定的属性而苦苦挣扎,当输入新文本时,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 }"/>

真的是这样吗?我的意思是 - 我只能让它工作,如果绑定在自定义视图中被命名为完全相同,并且消耗部分..

【问题讨论】:

  • 我已经更新了条目控制的答案以匹配您的问题。之前我使用过标签。请检查。

标签: c# xamarin.forms bindableproperty


【解决方案1】:

我只能让它工作,如果绑定在 自定义视图和消费部分..

绑定名称不必相同。请参考以下代码。

自定义控件

<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(nameof(EntryText), source: this));

OnPropertyChange(nameof(TitleText));

请参考https://www.youtube.com/watch?v=ZViJyL9Ptqg

我已测试此代码能够在条目文本从自定义视图更改时触发 propertyChanged 事件。

【讨论】:

    【解决方案2】:

    它很好地绑定了“绑定”值,但是在条目中输入的后续更改不会引发属性更改。

    从 BindableProperties property changes,BindableProperty MyEntryTextProperty 绑定 TextPropertyFromBindingContext,所以当你改变 TextPropertyFromBindingContext 时会触发 propertyChanged 事件,而不是改变 MyEntry 的值。

    您可以通过 Button.click 更改 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";
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 2017-07-27
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 2020-08-29
      • 2020-11-26
      相关资源
      最近更新 更多