0

I have a WPF application that makes use of Fody Commander to simplify the process of adding commands to the viewmodel.

However I am running into a strange issue where the values passed to the constructor of my class can affect if commands get initialised.

In the constructor of my view I have

public EditWindow(DataModel.Unit Unit)
{
    model = new ViewModels.EditViewModel(Unit);
    DataContext = model;
    model.CloseAction = new Action(Close);
    InitializeComponent();
}

In my viewmodel's constructor I have the following (where EditUnit is a public property with change notifications)

[ImplementPropertyChanged]
public class EditViewModel
{
    public DataModel.Unit EditUnit { get; set; }

    public EditViewModel (DataModel.Unit Unit)
    {
        if (Unit == null)
        {
            EditUnit = new DataModel.Unit();
            isnew = true;
        } else
        {
            EditUnit = Unit;
        }
    }

    [OnCommand("Close1")]
    public void Close()
    {
        this.CloseAction();
    }

    [OnCommand("SaveAndClose1")]
    public void SaveAndClose()
    {
        // Data validation here

        if (isnew) Ctx.Units.Add(EditUnit);
        Ctx.SaveChanges();
        this.CloseAction();
    }
    [OnCommandCanExecute("SaveAndClose1")]
    public bool SaveAndCloseCanExecute()
    {
        return <Data validation result>
    }
}

If create my view, passing in a unit, everything works beautifully. If create my view, passing in null, commands don't seem to get initialised and remain at null.

I am tearing my hair out over this, for now I have just shifted the creation of the new object out, to where I am creating the view (So I am always passing and object in, hence commands work properly)

But I can't understand at all why this would occur.

Hugoagogo
  • 1,598
  • 16
  • 34
  • Probably you should initialize your action, when Unit is null (EditUnit.CloseAction = new Action(Close)). If I am not mistaken, when you pass in an unit, you pass a reference to this object in memory. When it is null, you should create everything. – Sasha Nov 29 '17 at 07:24
  • You need to show more code, because from this one it's not possible to figure out where the problem is. – Evk Nov 29 '17 at 08:55
  • Added a bit more context to my viewmodel, with how I have defined my commands – Hugoagogo Nov 29 '17 at 21:46

1 Answers1

1

Commander injects command initialization at the end of constructor. Check out decompiled code with ILSpy or similar (jetBrains dotPeek). Very likely, you will see that your constructor code has been optimized and return early in case you pass null. This optimization which actually breaks your code happens because Fody injects code into IL, not into your source code. If you would add something like Trace.WriteLine(""); at the very end of constructor things would work again.