0

我正在尝试制作一个自定义控件以在多个地方使用它。问题是它与标签配合得很好,但是在进入时它甚至不会运行,它给了我

No property, BindableProperty, or event found for "EntryText"

这是我的自定义控件 Xaml:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

    <ContentView.Content>
        <StackLayout>
            <Label x:Name="MyLabel" />
            <Entry x:Name="MyEntry" />
        </StackLayout>
    </ContentView.Content>
</ContentView>

及其背后的代码

   public partial class MyCustomControl : ContentView
    {
        public static readonly BindableProperty LabelTextProperty = BindableProperty.Create(
            nameof(LabelText),
            typeof(string),
            typeof(MyCustomControl),
            propertyChanged: LabelTextPropertyChanged);

        private static void LabelTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (MyCustomControl)bindable;
            control.MyLabel.Text = newValue?.ToString();
            Debug.WriteLine("LabelTextPropertyChanged: " + control.MyEntry);
            Debug.WriteLine("LabelTextPropertyChanged: new value" + newValue);
        }

        public string LabelText 
        {
            get => base.GetValue(LabelTextProperty)?.ToString();
            set
            {
                base.SetValue(LabelTextProperty, value);
            }
        }


        public static  BindableProperty EntryBindableProperty = BindableProperty.Create(
            nameof(EntryText),
            typeof(string),
            typeof(MyCustomControl),
            propertyChanged:EntryBindablePropertyChanged
            );

        private static void EntryBindablePropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (MyCustomControl)bindable;
            Debug.WriteLine("EntryBindablePropertyChanged: " + control.MyEntry);
            Debug.WriteLine("EntryBindablePropertyChanged: new value" + newValue);
        }

        public string EntryText
        {
            get => base.GetValue(EntryBindableProperty)?.ToString();
            set
            {
                base.SetValue(EntryBindableProperty, value);
            }
        }
        public MyCustomControl()
        {
            InitializeComponent();
        }
    }

及其用法

<StackLayout>
        <local:MyCustomControl 
            LabelText="{Binding BindingLabel}" 
            EntryText="{Binding BindingEntry}"/>
    </StackLayout>

注意:我试图删除

 </ContentView.Content>

从我的 xaml 中,因为我已经看到了一些这样的例子,而且我也尝试在构造函数后面的代码中设置绑定

 public MyCustomControl()
        {
            InitializeComponent();
            MyEntry.SetBinding(Entry.TextProperty, new Binding(nameof(EntryText) , source: this));
        }

但也没有为条目工作。那么如果我想将值绑定到视图模型,我该如何解决这个问题并进行任何其他设置。提前致谢。

更新: @Jessie Zhang -MSFT 感谢您的帮助我非常感谢,但是我在 MyCustomControl 代码中发现了一个错误 => EntryTextProperty 是我必须声明 defaultBindingMode 才能将数据传递给 ViewModel 属性。所以我将 BindableProperty 代码更改为:

public static  BindableProperty EntryTextProperty = BindableProperty.Create(
            nameof(EntryText),
            typeof(string),
            typeof(MyCustomControl),
            defaultBindingMode: BindingMode.OneWayToSource,
            propertyChanged:EntryBindablePropertyChanged
            );
4

1 回答 1

0

您没有将Entry.TextandEntryText属性绑定在MyCustomControl.xaml

请参考以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CardViewDemo.Controls.MyCustomControl"
             
             x:Name="this"
             >
  <ContentView.Content>
        <StackLayout BindingContext="{x:Reference this}">
            <Label x:Name="MyLabel" Text="{Binding LabelText}" />
            <Entry x:Name="MyEntry" Text="{ Binding EntryText}"  />
        </StackLayout>
  </ContentView.Content>
</ContentView>

我用下面的代码做了一个测试,它工作正常。

        <local:MyCustomControl 
        LabelText="test1" 
        EntryText="test2"/>

更新:

从文档Create a property中,我们知道:

可绑定属性的命名约定是可绑定属性标识符必须与 Create 方法中指定的属性名称匹配,并附加“Property”。

因此,您可以将代码更改EntryBindableProperty EntryTextProperty,如下所示:

    public static readonly  BindableProperty EntryTextProperty = BindableProperty.Create(nameof(EntryText), typeof(string),typeof(MyCustomControl),string.Empty, BindingMode.TwoWay, null, EntryBindablePropertyChanged);

    public string EntryText
    {
        get => base.GetValue(EntryTextProperty)?.ToString();
        set
        {
            base.SetValue(EntryTextProperty, value);
        }

    }

而xaml代码是:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CardViewDemo.Controls.MyCustomControl"
             
             x:Name="template"
             >
  <ContentView.Content>
        <StackLayout >
            <Label x:Name="MyLabel"  Text="{Binding  Source={x:Reference template},Path=LabelText}"/>       

            <Entry x:Name="MyEntry"  Text="{Binding EntryText, Source={x:Reference template}}"  >
            </Entry>
       
        </StackLayout>
  </ContentView.Content>
</ContentView>
于 2022-02-23T07:06:42.700 回答