【问题标题】:Xamarin Froms Entry Custom Control does not workXamarin 表单条目自定义控件不起作用
【发布时间】:2022-02-24 16:48:23
【问题描述】:

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

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

这是我的自定义控件 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));
        }

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

更新: @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
            );

【问题讨论】:

    标签: xaml xamarin.forms bindableproperty


    【解决方案1】:

    您没有在MyCustomControl.xaml 中绑定Entry.TextEntryText 属性:

    请参考以下代码:

    <?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,我们知道:

    可绑定属性的命名约定是 属性标识符必须与在 创建方法,附加“属性”。

    因此,您可以将代码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>
    

    【讨论】:

    • 非常感谢您的快速回复,但是我尝试了您的代码并且它有效,但是当我尝试将这些文本绑定到后面的代码时,我得到了同样的错误。
    • 嗨@AbanoubRefaat,我已经更新了我的答案,您可以查看更新的部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 2020-11-03
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    相关资源
    最近更新 更多