首页 > 解决方案 > 从其 xaml 访问自定义控件的可绑定属性

问题描述

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

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

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

可以说我得到了以下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
    }
}

现在的问题是:

如何将 my 链接viewmodels Status property到 my views Status bindable property

标签: xamlxamarin.formsbindableproperty

解决方案


我通常创建一个辅助属性来将 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;
    }

推荐阅读