Xamarin Forms Entry 自定义控件不起作用
Xamarin Froms Entry Custom Control does not work
我正在尝试制作自定义控件以在多个地方使用它。
事情是它与标签一起工作正常但是当涉及到输入时它甚至不会 运行 它给了我
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));
}
但条目都不起作用。
那么我该如何解决这个问题,如果我想将值绑定到视图模型,它是否会进行任何其他设置。
提前致谢。
更新:
@Jessie Zhang -MSFT
谢谢你的帮助,我真的很感激,
但是我在 MyCustomControl 代码中发现了一个错误 => EntryText属性
是我必须声明 defaultBindingMode 才能将数据传递给 ViewModel 属性。
所以我将 Bindable属性 代码更改为:
public static BindableProperty EntryTextProperty = BindableProperty.Create(
nameof(EntryText),
typeof(string),
typeof(MyCustomControl),
defaultBindingMode: BindingMode.OneWayToSource,
propertyChanged:EntryBindablePropertyChanged
);
您没有在 MyCustomControl.xaml
中绑定 Entry.Text
和 EntryText
属性:
请参考以下代码:
<?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,我们知道:
The naming convention for bindable properties is that the bindable
property identifier must match the property name specified in the
Create method, with "Property" appended to it.
因此,您可以将代码 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>
我正在尝试制作自定义控件以在多个地方使用它。 事情是它与标签一起工作正常但是当涉及到输入时它甚至不会 运行 它给了我
No property, BindableProperty, or event found for "EntryText"
这是我的自定义控件 Xaml:
及其背后的代码 及其用法 注意:
我试图删除 来自我的 xaml 因为我见过这样的例子,
而且我还尝试在构造函数 但条目都不起作用。
那么我该如何解决这个问题,如果我想将值绑定到视图模型,它是否会进行任何其他设置。
提前致谢。 更新:
@Jessie Zhang -MSFT
谢谢你的帮助,我真的很感激,
但是我在 MyCustomControl 代码中发现了一个错误 => EntryText属性
是我必须声明 defaultBindingMode 才能将数据传递给 ViewModel 属性。
所以我将 Bindable属性 代码更改为: <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>
public MyCustomControl()
{
InitializeComponent();
MyEntry.SetBinding(Entry.TextProperty, new Binding(nameof(EntryText) , source: this));
}
public static BindableProperty EntryTextProperty = BindableProperty.Create(
nameof(EntryText),
typeof(string),
typeof(MyCustomControl),
defaultBindingMode: BindingMode.OneWayToSource,
propertyChanged:EntryBindablePropertyChanged
);
您没有在 MyCustomControl.xaml
中绑定 Entry.Text
和 EntryText
属性:
请参考以下代码:
<?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,我们知道:
The naming convention for bindable properties is that the bindable property identifier must match the property name specified in the Create method, with "Property" appended to it.
因此,您可以将代码 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>