从其 xaml 访问自定义控件可绑定属性

问题描述

我想在我的自定义视图中声明一个可绑定的属性并将其链接到相应的视图模型

我使用 MVVM 模式并希望将 ui 逻辑和数据逻辑彼此分开。所以我将我的状态和其他数据保存在视图模型中,并根据视图模型数据的变化更新我的视图。

这当然应该通过数据绑定来完成。

假设我得到了以下 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"
             xmlns:controls="clr-namespace:MyApp.Views.Controls"
             x:Class="MyApp.Views.Controls.MyView"
             x:DataType="controls:MyViewVm">
    <!--Todo: Content-->
</ContentView>

... 后面有这个代码...

using System.Runtime.CompilerServices;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace MyApp.Views.Controls
{
    [XamlCompilation(XamlCompilationoptions.Compile)]
    public partial class MyView : ContentView
    {
        public static readonly BindableProperty StatusProperty = BindableProperty.Create(nameof(Status),typeof(MyStatus),typeof(MyView));

        public MyStatus Status
        {
            get => (MyStatus)GetValue(StatusProperty);
            set => SetValue(StatusProperty,value);
        }

        public MyView()
        {
            InitializeComponent();
        }

        protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);

            switch (propertyName)
            {
                case nameof(Status):
                    // Todo: Do styling ...
                    break;
            }
        }
    }
}

... 以及这个视图模型和状态枚举:

namespace AbrechnungsApp.Views.Controls
{
    public class MyViewVm : viewmodelBase
    {
        public MyStatus Status { get; set; }
    }

    public enum MyStatus
    {
        Enabled,disabled,Readonly
    }
}

现在的问题是:

如何将我的 viewmodels Status property 链接到我的 views Status bindable property

解决方法

我通常会创建一个辅助属性来将 BindingContext 转换为适当的 VM 类:

private MyViewVm VM => (MyViewVm)BindingContext;

然后在可绑定属性中获取/设置 VM 属性:

public static readonly BindableProperty StatusProperty =
    BindableProperty.Create(
        nameof(Status),typeof(MyStatus),typeof(MyView),propertyChanged: (binding,old,new) =>
            {
                // Needed if your XAML uses two-way binding.
                Status = new;
            });

    public MyStatus Status
    {
        get => VM.Status;
        set => VM.Status = value;
    }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...