Xamarin - 将命令绑定到用户控件内对象的属性 [英] Xamarin - Binding Command to property of object inside User Control

查看:25
本文介绍了Xamarin - 将命令绑定到用户控件内对象的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几天前我开始学习 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":属性不存在,或不可分配,或值与属性之间的类型不匹配'

Xamarin.Forms.Xaml.XamlParseException: 'Position 8:24. Cannot assign property "Test1": Property does not exists, or is not assignable, or mismatching type between value and property'

这是我目前正在尝试开始工作的简化版本.

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 处理器.

When you create the identifier field, name this field by the name of the property as you registered it, plus the suffix Property. This field is your identifier for the dependency property, and it will be used later as an input for the SetValue and GetValue calls you will make in the wrappers, by any other code access to the property by your own code, by any external code access you allow, by the property system, and potentially by XAML processors.

将 DependencyProperty 标识符定义为所有者类型上的公共静态只读字段.

Define a DependencyProperty identifier as a public static readonly field on the owner type.

(这是 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 - 将命令绑定到用户控件内对象的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆