0

I'm generating buttons dynamically depending on the contents of a file.

My code only executes the RelayCommand once if I write it in this way:

var button = new Button();
button.Command = new RelayCommand(() => Messenger.Default.Send(new UseThisValue(value));
// button gets added to a treeview

but if I change it so that the lambda is set to the Tag propery it works every time

var button = new Button();
button.Tag = new Action(() => Messenger.Default.Send(new UseThisValue(value));
button.Command = new RelayCommand(button.Tag as Action);
// button gets added to a treeview

What is going on here? Is the assignmend keeping some reference count alive? I'm fairly new to C# so I might be overlooking something obvious to the more experienced developer.

RedX
  • 14,749
  • 1
  • 53
  • 76
  • 1
    Just so that you know, in mvvm the command should never know anything about the user interface. Commands should be defined in the view model, which is not supposed to know or care about the View. Then in the view you use binding to set the command for the button. – Brandon Kramer Mar 08 '17 at 14:34

1 Answers1

2

Garbage collection strikes again!

It's not terribly obvious here, but RelayCommand uses a WeakAction to store the reference to the "execute" method. This means the Action you hand in is subject to garbage collection.

Chances are good you can pull up Window's Performance Monitor, add the Gen0 garbage collection counter, and watch your button stop working at the same time a collection occurs. See my answer here for an example.

Community
  • 1
  • 1
Patrick Quirk
  • 23,334
  • 2
  • 57
  • 88
  • Shortly after I asked the question I came accross that answer and was very sure that was also my problem. – RedX Mar 08 '17 at 15:53