1

I have multiple Switches in a Xaml page and I am struggling to grasp the concept of MVVM when using Switches and handling State Changes etc. I am trying within a view model to capture the object and argument within the ViewModel which is available within the xaml.cs file.

A standard Switch Xaml from Microsoft on Switches.

<Switch Toggled="OnToggled" />

The same page Xaml.cs File

void OnToggled(object sender, ToggledEventArgs e)
{
    // I have the sender so can target the switch now and change values colours etc.
}

Now it is this massive cough for me leap into Mvvm which I am failing to grasp.

I have followed every single guide/demo/tutorial on Mvvm but I can not figure out how doing the near same thing using Maui Community Toolkit and using a View Model I can cut out the Xaml.cs element of my code. As I believe the page should not be aware of the View vice versa.

My current code is as follows :- SettingsPage.xaml

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyProject.Views.SettingsPage"
             xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             xmlns:vm="clr-namespace:MyProject.ViewModels"
             x:DataType="vm:SettingsPageViewModel"
             BackgroundColor="{DynamicResource PageBackGround}">

    <ContentPage.Content>
        <StackLayout>
            <Switch IsToggled = "True"
                <Switch.Behaviors>
                    <mct:EventToCommandBehavior
                        x:TypeArguments="x:Object"
           EventName="Toggled"
           Command="{Binding ToggledCommand}" />
                </Switch.Behaviors>
            </Switch>              
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

SettingsPage.xaml.cs

namespace MyProject.Views;

public partial class SettingsPage : ContentPage
{
    ILogger<SettingsPage> _logger;
    public SettingsPage(SettingsPageViewModel settingsPageViewModel, ILogger<SettingsPage> logger)
    {
        InitializeComponent();
        BindingContext = settingsPageViewModel;

        _logger = logger;
        _logger.LogInformation("Navigation to Settings Page.");
    }
}

SettingsPageViewModel.cs

namespace MyProject.ViewModels
{
    public partial class SettingsPageViewModel : BaseViewModel
    {
        ILogger<SettingsPageViewModel> _logger;
        LogController LogController;
        public SettingsPageViewModel(ILogger<SettingsPageViewModel> logger)
        {
            _logger = logger;
            LogController = new LogController();
        }

        // Here I want to capture the object so that I can have multiple switches on the page and be able to identify them to change values etc for what states they are in.
        [RelayCommand]
        public void Toggled(ToggledEventArgs e) 
        {
            var bangingMyheadAgainstAWall = "e";
        }
    }       
}

I have also tried without using the EventToCommandBehaviour and just used standard Toggled, Istoggled, OnToggled, IWishIknewWhichSwitchWasToggled but I just can not get the properties through to the view model or I have backed myself in to a corner and am a little confused.

Any help/ push in the correct direction to help me handle this situation correctly would be greatly appreciated. Thanks in Advance.

1
  • 1
    Why don’t you just bind IsToggled to a property in your VM? Commented Jul 6, 2023 at 11:46

1 Answer 1

6

It seems like you're overcomplicating things. You can forget mostly about events and getting/setting values that way. The key here is data binding.

IsToggled, like most properties in .NET MAUI, is a bindable property. This means that you can bind a property from your view model to it, and the control will update that property whenever something changes, no event needed.

You're mostly there with your code though! You can remove the event to command stuff, you don't need it. Also remove

Change your Switch to: <Switch IsToggled = "{Binding MyProperty}"/>

And on your SettingsPageViewModel add a property like this, this is assuming the use of the MVVM Toolkit:

[ObservableProperty]
private bool myProperty;

Now whenever the switch is toggled, the property in code should reflect the new value and vice versa.

From what I understand that you're doing is your thought process was: I need an event to catch the switch being toggled, but that's not MVVM, so I need a Command to do the same thing.

Usually that's not the case. A Command really only is for executing logic, not setting or retrieving control values.

If I can offer a last piece of unsolicited advice: if you're just starting out with MVVM, try doing so without the Toolkit. I love the MVVM Toolkit, it's amazing, but it also has a lot of magic. If you know your way around MVVM it's a productivity boost and can be really helpful. If you're just starting, it will only add to the confusion.

Sign up to request clarification or add additional context in comments.

3 Comments

thank you for the explanation, the thing I am missing completely is I wish to change the switch colours, but have to do this in the code behind due to this [github.com/dotnet/maui/issues/10099](this current issue). Getting the value of the bool is fine, but if I have 3 switches and I need the object returned to my view model so I can target it to change its values. I hope to god this makes sense :). The key thing is, Currently my App has a black background and switches off state does not work on Black backgrounds so I need to work in the fix.
Ah alright, so first: that bug is fixed so it will be working over time. Second: I think that has little to do with MVVM or anything at all haha. There is a workaround for the time being posted here but as it's a workaround I wouldn't worry too much about anything being MVVM or not to be honest. I'm not 100% sure what you're trying to do, so I don't think I'm able to help you any further this way unfortunately.
Thank you anyway as your answer did help, I am one step closer :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.