简体   繁体   中英

Accessing Xamarin.Forms inside ViewModel

I am very new to Cross platform development in Xamarin.forms. My code should be highly unit testable and I have created a ViewModel class to communicate between my View and the Model . I want to know, If we are going to access Xamarin.forms (using Xamarin.Forms;), inside the viewmodel, is it a bad practice or violating MVVM concept. If so How we can use Command inside ViewModel to bind with the view.

Thanks

Accessing the view from the view model is indeed "against" the MVVM principle. So, you're right on that! Binding a Command though, isn't that hard and works just as any other binding that you might've used.

In your view model, just define a property for the Command :

public class YourViewModel
{
    public Command YourCommand { get; set; }
}

Then in the constructor define the logic that should be executed:

public YourViewModel()
{
    YourCommand = new Command(() =>
    {
        Console.WriteLine("TADA!");
    });
}

Of course, you could define it is it's own separate method or declare it another way. For brevity, I have done it inline for now.

To bind to it from XAML, simply do:

<Button Text="Make it so!" Command="{Binding YourCommand}" />

and make sure that you have set the BindingContext property on your page to the view model. If you are using an MVVM framework you might have already done so.

At some point, you will probably want to bind to a cell in a ListView or similar. In that case, keep in mind that the scope changes. You are then binding to the view model behind that cell and not the page. So, you will have to make a reference to the page to reach that BindingContext . But cross that bridge when you get there, just keep in mind that there is something special about it.

Use below code, so you don't need to import Xamarin.Forms in your ViewModel:

ButtonBehavior

 public class ButtonBehavior : Behavior<Button>
    {
        protected override void OnAttachedTo(Button bindable)
        {
            base.OnAttachedTo(bindable);
            bindable.Clicked += Bindable_Clicked;
        }

        private void Bindable_Clicked(object sender, EventArgs e)
        {
            //Use you logic here
        }

        protected override void OnDetachingFrom(Button bindable)
        {
            base.OnDetachingFrom(bindable);
            bindable.Clicked -= Bindable_Clicked;
        }
    }

View

    <Button Text="Click Me" HeightRequest="50" WidthRequest="80">
        <Button.Behaviors>
            <behavior:ButtonBehavior/>
        </Button.Behaviors>
    </Button>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM