Search code examples
c#wpfmvvmmodel-bindingcommand-pattern

wpf MvvM Command data-context issue


I googled all I could but could not find exactly what I was looking for. I have few issues...

This is my code structure:

My Command Class:

 public class BrowseCommand : ICommand 
 {
   //Code here
 }

Inside ViewModel:

public class ExampleViewModel
{
    public ExampleViewModel()
    {
        BrowseCommand = new BrowseCommand();
    }

    public ICommand BrowseCommand
    {
        get;
        private set;
    }
  //More Code...
}

MainWindow.xaml.cs:

 public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ExampleViewModel();
    }
}

MainWindow.xaml:

Window x:Class="Ship32RcParser.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" >

   <Grid>
       <Button  Content="Browse" Command="{Binding BrowseCommand}"/>
       <Button  Content="Search" Command="{Binding I_NEED_HELP_HERE}"  />
   </Grid>
</Window>



I understand that my Browse works fine because of MainWindow.xaml.cs has

DataContext = new ExampleViewModel();

However I do not like that

  1. I do not want to have anything in .cs file
  2. How do i have more than one datacontext - meaning if I want to have command from different ViewModel classes... I know its possible but its going to be bit ugly...

When I was searching for solutions I came across dependencies. For example I could do in my xaml file something like this

xmlns:local="clr-namespace:myMvvMwpfProj.ViewModel"

and then use "local". However, when I tried it did not work as I expected it to work... I also saw something like

xmlns:local="using:myMvvMwpfProj.Command"

can someone explain those too please. Does "local" give me an access to classes? If I have CommandA, CommandB, CommandC classes. Should I be able to do local:CommandA.ExecuteFoo ?

I guess the big question is how do I reference/access properties from different objects. in Xaml

thank you all in advance


Solution

  • You can set up the datacontext in your View with <Grid DataContext = "{Binding}">

    You have 1 viewmodel per view but you can have many bound commands! I suggest you look up Josh Smiths RelayCommand as this make this so much easier! A guide is here:

    Create a new class

    class RelayCommand : ICommand
    {
        private Action<object> _action;
    
        public RelayCommand(Action<object> action)
        {
            _action = action;
        }
    
        #region ICommand Members
    
        public bool CanExecute(object parameter)
        {
            return true;
        }
    
        public event EventHandler CanExecuteChanged;
    
        public void Execute(object parameter)
        {
                _action(parameter);
        }
    
        #endregion
    }
    

    And in your ViewModel

        public ICommand BrowseCommand {get; set;}
        public ICommand SearchCommand {get; set;}
    
        public ExampleViewModel()
        {
            this.BrowseCommand = new RelayCommand(new action<object>(MethodNameEnteredHere);
            this.SearchCommand = new RelayCommand(new action<object>(OtherMethodNameEnteredHere);
        }
    

    So, your xaml would be

    <Grid DataContext = "{Binding}">
           <Button  Content="Browse" Command="{Binding BrowseCommand}"/>
           <Button  Content="Search" Command="{Binding SearchCommand}"  />
     </Grid>