I'm trying to understand some odd behavior I'm seeing with a MVVM RelayCommand whose action is a closure capturing a local variable.
Minimum viable code sample:
using GalaSoft.MvvmLight.CommandWpf;
namespace WpfApplication3
{
public partial class MainWindow
{
public RelayCommand DoIt { get; }
int i = 0;
public MainWindow()
{
DoIt = new RelayCommand( () =>
{
System.Console.WriteLine( "doing it!" );
button.Content = (++i).ToString();
} );
InitializeComponent();
}
}
}
XAML:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
SizeToContent="WidthAndHeight">
<Button x:Name="button" Content="Hit me" Command="{Binding DoIt, RelativeSource={RelativeSource AncestorType=Window}}"/>
</Window>
When you tap the "Hit me" button, the label changes to a number which increments for every subsequent tap.
Since i
is only used by the RelayCommand
action, I want to move the declaration to the constructur as a local variable. But when I do, I get very odd behavior: The command either won't fire at all, or fires once and then stops.
Interestingly enough, if I nix the RelayCommand
and wire the closure to the button's Click
event, it works no matter where I define i
. So it must be something in the way RelayCommand
is handling the closure.
Any guesses?