1

I want to declare a bindable property in my custom view and link it to the corresponding viewmodel.

I use the MVVM pattern and want to separate ui logic and data logic from eachother. So I keep my status and other data in the viewmodel and update my view according to viewmodel data changes.

This of course should be done by data binding.

Lets say I got the following 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>

... with this code behind ...

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;
            }
        }
    }
}

... and this viewmodel and status enum:

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

    public enum MyStatus
    {
        Enabled,
        Disabled,
        Readonly
    }
}

Now the question is:

How do I link my viewmodels Status property to my views Status bindable property?

Gabriel Weidmann
  • 756
  • 12
  • 16
  • You'll need to start by implementing INotifyPropertyChanged on your VM. Take a look [here](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm#interactive-mvvm) for an example what this might look like. – Andrew May 28 '21 at 14:20
  • Yeah, of course. I was forgetting about this but in my real projects I have this thing implemented. I will add it. But this is not the question, binding works as exspected, I just don't know HOW to bind to the viewmodel. – Gabriel Weidmann May 28 '21 at 14:20

1 Answers1

0

I typically create a helper property to cast BindingContext to the appropriate VM class:

private MyViewVm VM => (MyViewVm)BindingContext;

Then get/set VM properties in the bindable property:

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;
    }
ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196