AdmiralCat3
AdmiralCat3

Reputation: 99

Changing values of DataContext in Command in WPF

I want to change value of ViewModel property (which is binded with DataContext). Extremely easy with classic Events, with Commands it becomes formidable task. This is my code:

public partial class MainWindow : Window
    {
        ViewModel _vm = new ViewModel();
        public MainWindow()
        {
            InitializeComponent();

            _vm.BtnClick = new BtnClick();

            DataContext = _vm;
        }
    }

public class BtnClick : ICommand
    {
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            Debug.WriteLine(parameter.ToString());
        }
    }

public class ViewModel
    {
        public ICommand BtnClick { get; set; }
        public string Input { get; set; }
        public string Output { get; set; }
    }
<StackPanel>
        <TextBox Text="{Binding Input}"></TextBox>
        <TextBlock Text="{Binding Output}"></TextBlock>
        <Button Command="{Binding Path=BtnClick}" CommandParameter="{Binding Input}">Translate</Button>
    </StackPanel>

Command properly takes value from TextBox, now i want to do things with this value and save it to Output. And problem is from Command perspective i cannot access both DataContext and ViewModel.

Upvotes: 0

Views: 944

Answers (1)

Andy
Andy

Reputation: 12276

The implementation of any command is usually in a viewmodel.

A framework or helper class is routinely used.

For example:

https://riptutorial.com/mvvm-light/example/32335/relaycommand

public class MyViewModel { .....

public ICommand MyCommand => new RelayCommand(
   () =>
  {
    //execute action
    Message = "clicked Button";
  },
  () =>
  {
    //return true if button should be enabled or not
    return true;
  }

);

Here, there is an anonymous method with that "clicked button" in it.

This will capture variables in the parent viewmodel.

You may therefore set a public property in the viewmodel that's bound to the text property in your view.

For the view to respond you will need to implement inotifypropertychanged and raise property changed in the setter of that public property.

https://learn.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-implement-property-change-notification.

From the above.

If PersonName was bound to a textblock in the view.

  public string PersonName
  {
      get { return name; }
      set
      {
          name = value;
          // Call OnPropertyChanged whenever the property is updated
          OnPropertyChanged();
      }
  }

In the command you can do:

 PersonName = "Andy";

Which calls the setter of PersonName and a textblock bound to PersonName will read the new value.

Upvotes: 0

Related Questions