Reputation: 193322
This code shows that the Delegate Command from the Visual Studio MVVM template works differently when used with MenuItem and Button:
Does anyone know why this is the case?
MainView.xaml:
<Window x:Class="TestCommand82828.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:TestCommand82828.Commands"
Title="Main Window" Height="400" Width="800">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Command="{Binding DoSomethingCommand}" Header="Do Something" />
</MenuItem>
</Menu>
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top">
<Button Command="{Binding DoSomethingCommand}" Content="test"/>
<TextBlock Text="{Binding Output}"/>
<TextBox Text="{Binding TheInput}"/>
</StackPanel>
</DockPanel>
</Window>
MainViewModel.cs:
using System;
using System.Windows;
using System.Windows.Input;
using TestCommand82828.Commands;
namespace TestCommand82828.ViewModels
{
public class MainViewModel : ViewModelBase
{
#region ViewModelProperty: TheInput
private string _theInput;
public string TheInput
{
get
{
return _theInput;
}
set
{
_theInput = value;
OnPropertyChanged("TheInput");
}
}
#endregion
#region DelegateCommand: DoSomething
private DelegateCommand doSomethingCommand;
public ICommand DoSomethingCommand
{
get
{
if (doSomethingCommand == null)
{
doSomethingCommand = new DelegateCommand(DoSomething, CanDoSomething);
}
return doSomethingCommand;
}
}
private void DoSomething()
{
Output = "did something, the input was: " + _theInput;
}
private bool CanDoSomething()
{
return true;
}
#endregion
#region ViewModelProperty: Output
private string _output;
public string Output
{
get
{
return _output;
}
set
{
_output = value;
OnPropertyChanged("Output");
}
}
#endregion
}
}
Upvotes: 0
Views: 2249
Reputation: 204219
I think what you're seeing is because MenuItems don't take focus away from a TextBox, and by default, a TextBox only pushes changes back to its bound source when focus shifts away from it. So when you click the button, the focus shifts to the button, writing the TextBox's value back to _theInput. When you click the MenuItem, however, focus remains in the TextBox so the value is not written.
Try changing your TextBox declaration to:
<TextBox Text="{Binding TheInput,UpdateSourceTrigger=PropertyChanged}"/>
Or alternatively, try switching to DelegateCommand<t>
, which can receive a parameter, and pass the TextBox's text to it:
<MenuItem Command="{Binding DoSomethingCommand}"
CommandParameter="{Binding Text,ElementName=inputTextBox}" />
...
<TextBox x:Name="inputTextBox" Text="{Binding TheInput}" />
Upvotes: 3