-1

我在使用可绑定属性时遇到了一些困难,并且在输入新文本时不会触发 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 }"/>

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

4

2 回答 2

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 事件。

于 2021-03-21T04:33:06.047 回答
0

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

从 Bindable Properties 属性更改,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";
    }
}
于 2021-03-22T02:30:51.707 回答