0

I see some buggy code from WPF project. ViewModelBase and RelayCommand classes are from MVVM Light. This is viewmodel class of a child window

class TOSelectionWindowViewModel : ViewModelBase
{
    ObservableCollection<ToElement> MyTo;

    public RelayCommand<ToAll> ToAddCmd { private set; get; }

    private Element selectedelement;
    public Element SelectedElement
    {
        get { return selectedelement; }
        set
        {
            if (value != selectedelement)
            {
                selectedelement = value;
                RaisePropertyChanged("SelectedElement");
            }
        }
    }

    public TOSelectionWindowViewModel(Element e)
    {
        SelectedElement = e;

        System.Console.WriteLine( object.ReferenceEquals(e, SelectedElement) ); // True
        System.Console.WriteLine(object.Equals(e, SelectedElement)); // True

        ToAddCmd = new RelayCommand<ToAll>((Added) =>
        {
        if (Added == null )
        {
            MessageBox.Show("COMMAND EXECUTED", "Message",
                         MessageBoxButton.OK, MessageBoxImage.Error);
               return;
            }
            using (ToElementEntities my = new ToElementEntities(@"Data Source = " + Globals.Directory + @"\DB\" + Globals.SelectedVessel.ID + @"\El_TO.db"))
            {
                my.ToElements.Add(new ToElement { ElementID = e.ID });
                my.SaveChanges();
                MyTo = new ObservableCollection<ToElement>(my.ToElements.Where(i => i.ElementID == SelectedElement.ID));
            }
        });
    }
}

This window is shown like this:

TOSelectionWindow toselectionWindow = new TOSelectionWindow(SelectedElement);
//SelectedElement is a property of this VM
if (toselectionWindow.ShowDialog() == true)
{
    ...
}

Problem is that ToAddCmd is executed or not executed randomly after I'm opening and closing this child window. When I'd changed

my.ToElements.Add(new ToElement { ElementID = e.ID });

to

my.ToElements.Add(new ToElement { ElementID = SelectedElement.ID });

it started to work just fine even corrected line of code isn't called due to return statement. Can you explain me why?

L. Volkov
  • 9
  • 1
  • 1
    What actually triggers the command? Is it bound to something in XAML? – Bradley Uffner Oct 18 '17 at 13:44
  • What about putting a breakpoint in the command's execute method and looking at the call stack for hints? – 15ee8f99-57ff-4f92-890c-b56153 Oct 18 '17 at 13:45
  • @BradleyUffner Yes, it's bound to a button in a View: – L. Volkov Oct 18 '17 at 14:05
  • 1
    @EdPlunkett Had same idea, in both cases call stacks are same and in case of not executing command breakpoint doesn't work – L. Volkov Oct 18 '17 at 14:07
  • I just want to understand why 1) I should use additional property in this VM to hold Element object in it and can't use contructor's parameter and 2) all-time normal executing of this command depends on the code which this command execute() method contains – L. Volkov Oct 18 '17 at 14:14
  • @L.Volkov From the links grek40 just posted, it sounds like this is due to `RelayCommand` allowing the `Action` of your command to get garbage collected, due to it holding the only reference to it with a `WeakReference`. The solution seems to be not using an anonymous function as the action. I've never run in to this myself, so I can't say with cirtainty, but it sounds very plausable. – Bradley Uffner Oct 18 '17 at 14:19
  • ...or use one of the tricks in his 2nd link to keep it from getting collected. – Bradley Uffner Oct 18 '17 at 14:22
  • @grek40 it seems that so, thanks! – L. Volkov Oct 18 '17 at 14:29
  • 1
    Well then feel free to upvote my answer over there ;), but this one should be closed as a duplicate. Don't delete it though, it's actually good to have a few duplicates with different titles around, as long as a problem is not part of the *common knowledge* – grek40 Oct 18 '17 at 14:34

0 Answers0