RelayCommand from lambda with constructor parameters

If in the XAML file I attach the "Command" button from the following class, clicking the button does not cause DoIt:

class Thing()
{
  public Thing(Foo p1)
  {
    Command = new RelayCommand(() => DoIt(p1));
  }

  private DoIt(Foo p)
  {
    p.DoSomething();
  }

  public ICommand Command { get; private set; }
}

However, it works if I initialize the field from p1 and pass the field as a parameter to a method call inside the lambda:

class Thing()
{
  private Foo field;
  public Thing(Foo p1)
  {
    field = p1;
    Command = new RelayCommand(() => DoIt(field));
  }

  private DoIt(Foo p)
  {
    p.DoSomething();
  }

  public ICommand Command { get; private set; }
}

Why doesn't the former work, but does the latter work as expected?

Perhaps relevant: How do shutters work behind the scenes? (FROM#)

EDIT. To clarify, the following will also work for me. However, I would still like to know why the second example did what I expected, but the first did not.

class Thing()
{
  private Foo field;
  public Thing(Foo p1)
  {
    field = p1;
    Command = new RelayCommand(DoIt);
    //Command = new RelayCommand(() => DoIt()); Equivalent?
  }

  private DoIt()
  {
    field.DoSomething();
  }

  public ICommand Command { get; private set; }
}
+4
source share
2 answers

, , .

MVVM Light RelayCommand. execute canececute WeakAction _execute WeakFunc<bool> _canExecute . WeakAction GC , - - .

, : viewmodel, , WeakAction , . Action . RelayCommand, , GC , RelayCommand .

, . WeakAction - . Delegate.Target Delegate.MethodInfo. .

:

  • : () => I_dont_access_anything_nonstatic()
  • -: () => DoIt(field) viewmodel, viewmodel , .
  • : () => DoIt(p1) . , - GC -

:, , Roslyn: Roslyn, , (2) Roslyn. , , .

+2

, DoIt , lamda.

() => DoIt(p1);

(, ).

mvvm-light :

class Thing
{
    public Thing()
    {
       Command = new GalaSoft.MvvmLight.Command.RelayCommand<bool>(DoIt);
    }

    private void DoIt(bool p)
    {
       p.DoSomething(p);
    }

    public System.Windows.Input.ICommand Command { get; private set; }
}

Button "Command".

0

Source: https://habr.com/ru/post/1607559/


All Articles