问题描述
几天前我开始学习 XAML,但在解决这个问题时遇到了麻烦.
I have began learning XAML a few days ago and I have a trouble with wrapping my head around this problem.
在 Xamarin Forms 中,我想创建一个包含标签和按钮的用户控件,并且能够从使用我的用户控件的另一个页面将命令绑定到 XAML 中的用户控件.
In Xamarin Forms, I want to create a user control which will contain a label and a button and be able to bind a command to usercontrol in XAML from another page which uses my user control.
我目前遇到异常:
Xamarin.Forms.Xaml.XamlParseException: '位置 8:24.无法分配属性Test1":属性不存在,或不可分配,或值与属性之间的类型不匹配'
这是我目前正在尝试开始工作的简化版本.
Here is a dumbed down version of it I am currently trying to get to work.
我的自定义控件 XAML
My Custom Control 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="App3.Controls.Control1">
<StackLayout>
<Button Command="{Binding Test1}" Text="Test"/>
</StackLayout>
</ContentView>
使用我的自定义控件 XAML 进行控制
Control using my Custom Control XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App3"
xmlns:controls="clr-namespace:App3.Controls"
x:Class="App3.MainPage">
<controls:Control1 Test1="{Binding Test2}" />
</ContentPage>
我的自定义控件代码隐藏
My Custom Control Codebehind
using System.Windows.Input;
using Xamarin.Forms;
namespace App3.Controls
{
public partial class Control1 : ContentView
{
private static readonly BindableProperty controlProperty = BindableProperty.Create("Test1", typeof(ICommand), typeof(Control1), null);
public Control1()
{
InitializeComponent();
}
public ICommand Test1
{
get
{
return (ICommand)GetValue(controlProperty);
}
set
{
SetValue(controlProperty, value);
}
}
}
}
使用自定义控件查看页面模型
View Model of page using Custom Control
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Xamarin.Forms;
namespace App3
{
public class MainPageViewModel : INotifyPropertyChanged
{
public MainPageViewModel()
{
this.Test2 = new Command(test);
}
public void test()
{
Application.Current.MainPage.DisplayAlert("it works", "it works", "it works");
}
public ICommand Test2
{
get; set;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
推荐答案
如果您希望从 Xaml 检测到您的 BindableProperty 并且可绑定,则需要遵循一些命名约定:
There are a few naming convention to follow if you want your BindableProperty detected, and bindable, from Xaml:
当您创建标识符字段时,请使用您注册时的属性名称以及后缀 Property 来命名该字段.此字段是您的依赖项属性的标识符,稍后将用作您将在包装器中进行的 SetValue 和 GetValue 调用的输入,通过您自己的代码对属性的任何其他代码访问,通过任何外部代码访问您允许,通过属性系统,并可能通过 XAML 处理器.
和
将 DependencyProperty 标识符定义为所有者类型上的公共静态只读字段.
(这是 DependencyProperty 的文档,但在这种情况下它非常适用于 BindableProperties.请参阅 https://msdn.microsoft.com/en-us/library/ms753358(v=vs.110).aspx)
(this is the documentation for DependencyProperty, but it applies to BindableProperties quite well in this case. See https://msdn.microsoft.com/en-us/library/ms753358(v=vs.110).aspx)
您可以通过替换来修复您的代码
You can fix your code by replacing
private static readonly BindableProperty controlProperty = BindableProperty.Create("Test1", typeof(ICommand), typeof(Control1), null);
public ICommand Test1
{
get { return (ICommand)GetValue(controlProperty); }
set { SetValue(controlProperty, value); }
}
由
public static readonly BindableProperty Test1Property = BindableProperty.Create("Test1", typeof(ICommand), typeof(Control1), null);
public ICommand Test1
{
get { return (ICommand)GetValue(Test1Property); }
set { SetValue(Test1Property, value); }
}
这应该可以防止属性检测问题.
That should prevent the property detection issue.
为了让您的全部内容正常工作,Button 命令绑定应该将其源设置为控件本身,并且您应该将 MainPageViewModel
设置为 的
BindingContext
for 主页
.
to get your full stuff working, the Button command binding should have it's source set to the control itself, and you should set your
MainPageViewModel
as BindingContext
for MainPage
.
这篇关于Xamarin - 将命令绑定到用户控件内对象的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!