Question

I've abandoned the MVVM midway through app development just to get this app out.

I've written a method in the code behind to update the database/datagrid etc.

My application navigation is using Commands to the ViewModel firing some event but never touches the code-behind except one time to initialize the class.

So basically I push the button one time and it works with the default initial setting but I can't call my code-behind Update() method anymore once the view as been intialized.

How can I call this code-behind method from the view model?

Thanks!!

Update code

 //Navigation ViewModel
//PaneVm.cs

public CommandExtension NewAssignmentCommand { get; set; }
    private void CreateCommands()
    {
        NewAssignmentCommand = new CommandExtension(NewAssignment, CanNewAssignment);
}
GlobalCommands.NewAssignmentCommand = NewAssignmentCommand;

private bool CanNewGroupAssignment(object obj)
    {
        return true;
    }

    private void NewGroupAssignment(object obj)
    {
        OnPropertyChanged("NewGroupAssignmentCommand");
    }


//MainVM.cs
// [Events]
    void _PaneVm_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "NewGroupAssignmentCommand")
            WorkspaceVm.CurrentVm = new NewAssignmentsVm();
}


//NewAssignmentVm.cs
//Constructor
    public NewAssignmentsVm()
    {
        var rc = new RepositoryContext();

        _RoResearchers = new ObservableCollection<Researcher>(rc.ResearcherData.GetAllResearchers());

        _QuarterDateTime = DateTime.Now;

        CreateCommands();
    }

//NewAssignment.cs
//Code-behind
//The method
private void UpdateGrid()
    {
        report_datagrid.ItemsSource = null;

        using (var rc = new RepositoryContext())
        {
            if (quarter_datepicker.SelectedDate != null)
            {
                if (!String.IsNullOrEmpty(reportType))
                    researchers = rc.ResearcherData.GetResearchersWeeksByQuarter(Convert.ToDateTime(quarter_datepicker.SelectedDate), reportType).ToList();

            }
        }
    }

UPDATE 2:

I solved my problem based off this answer. I created a Global Action

 public static class GlobalCommands 
 { 
 public static Action UpdateGrid { get; set; } 
 } 

Then in my code-behind constructor I set the value public

   MyCodeBehind() 
   { 
       GlobalCommands.UpdateGrid = new Action(() => this.UpdateGrid()); 
   } 

Didn't need to bind to the context again. Everything else was the same. Thank you

Was it helpful?

Solution

Main idea is:

class MyCodeBehind
{
   public MyCodeBehind()
   {
      Action action = new Action(()=> this.SomeMethodIWantToCall());
      var myVM = new MyVM(action); // This is your ViewModel
      this.DataContext = myVM;
   }

   private void SomeMethodIWantToCall(){...}
}

class MyVM
{
    private Action action;

    public MyVM(Action someAction)
    {
       this.action = someAction;
    }

    private void SomeMethodInVM()
    {
        this.action(); // Calls the method SomeMethodIWantToCall() in your code behind
    }
}

OTHER TIPS

Instead of letting code-behind know about viewmodel, You can make use of NotifyOnSourceUpdated in your xaml binding.

Something like this:

<TextBlock Grid.Row="1" Grid.Column="1" Name="RentText"
  Text="{Binding Path=Rent, Mode=OneWay, NotifyOnTargetUpdated=True}"
  TargetUpdated="OnTargetUpdated"/>

Here, 'OnTargetUpdated' is a handler in your code behind. This handler will be invoked when "Rent" property of ViewModel is changed.

Details at MSDN

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top