0

I have a few checkboxes where the UI will change based on their status. In the code I send a message everytime the checkbox is click, everything works fine but I'm not sure if this is the most effective way to handle CheckBoxes. Sorry but I'm new to the whole WPF/MVVM.

Here is how I'm doing it...

XAML:

<Grid x:Name="LayoutRoot">
    <CheckBox x:Name="checkBox" Command="{Binding CheckBoxCommand}" Content="My Check Box"/>
</Grid>

ViewModel:

namespace MvvmLightCheckBoxes.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        public RelayCommand CheckBoxCommand { get; set; }
        private Boolean _isCheckBoxChecked = true;

        public MainViewModel(IDataService dataService)
        {
            CheckBoxCommand = new RelayCommand(() => checkBoxClick());
        }

        private void checkBoxClick()
        {
            if (_isCheckBoxChecked) {
                Messenger.Default.Send(new MessageFromMain { isBoxChecked = _isCheckBoxChecked });
                _isCheckBoxChecked = false;
            }else {
                Messenger.Default.Send(new MessageFromMain { isBoxChecked = _isCheckBoxChecked });
                _isCheckBoxChecked = true;
            }
        }

    }
}

Codebihind:

namespace MvvmLightCheckBoxes
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Messenger.Default.Register<MessageFromMain>(this, m => ReceivedMessageFromMain(m));
        }

        private void ReceivedMessageFromMain(MessageFromMain m)
        {
            if (m.isBoxChecked) {
                Console.WriteLine("Box is checked");
            }
            else {
                Console.WriteLine("Box is unchecked");
            }
        }
    }
}

Model:

namespace MvvmLightCheckBoxes.Model
{
    class MessageFromMain
    {
        public Boolean isBoxChecked { set; get; }
    }
}

Is this an acceptable way to handle checkBoxes when using MVVM?

fs_tigre
  • 9,459
  • 12
  • 53
  • 111

1 Answers1

2

No, normally you bind the IsChecked property:

<CheckBox IsChecked="{Binding CheckStatus}" Content="Click Me"/>

And then in your view model you do this:

private bool _CheckStatus;
public bool CheckStatus
{
    get { return this._CheckStatus; }
    set
    {
        if (this._CheckStatus != value)
        {
            this._CheckStatus = value;
            RaisePropertyChanged(() => this.CheckStatus);
        }
    }
}

Ordinarily having a regular property with get/set accessors is enough, you only need to add the property change notification if you want the binding to be two-way i.e. so that you can also toggle the state in the view model code.

Also take that code out of MainWindow. If you ever find yourself adding code to your Window classes then it means you're probably doing something wrong.

Mark Feldman
  • 13,965
  • 2
  • 24
  • 47
  • I see, thank you for the code sample. Question, what do you mean by ‘take code from the MainWindow’? Are you referring to the codebehind? If yes, it’s currently the easiest way for me to manipulate my UI controls from the viewModels. – fs_tigre Jul 25 '18 at 02:38
  • 1
    It may sometimes be the easiest option, but it's not MVVM. The whole point of MVVM is to decouple your view logic from the view itself. If you're going to manipulate view elements directly in code behind then to be honest there's not really any point in doing MVVM at all, you may as well just stick to "regular" WPF. You do need to be doing proper data-binding though if you want the full power that WPF offers. – Mark Feldman Jul 25 '18 at 06:33
  • @ Mark Feldman Would you mind demonstrating how would you change the background color of a label from the ViewModel without using code-behind? I want to do it the best possible way. Thanks – fs_tigre Jul 25 '18 at 11:03
  • 1
    More than happy to, but post it as a separate question (I'll keep an eye out for it). The SO police get a bit tetchy when you start deviating from the straight-and-narrow. ;) – Mark Feldman Jul 25 '18 at 11:17
  • @ Mark Feldman - I already asked this question and the answer I got is the method I'm currently using but I'm curious to see an example that doesn't involve the codebehind. Here is the thread: https://stackoverflow.com/questions/47022762/how-to-interact-with-ui-elements-when-using-mvvm-mvvmlight-in-a-wpf-app – fs_tigre Jul 25 '18 at 11:29
  • 1
    Just added an answer of my own. – Mark Feldman Jul 25 '18 at 11:50