MVVM: Editing a Client. How to find a workspace with the same object and create a new workspace from another workspace

Like this question , I am learning MVVM using a sample created by Josh Smith and I wanted to add update functionality.

There are two problems (not covered in the above question):

  • What is the best and easiest way to create a workspace from another workspace?
  • How to find if there is a workspace for editing the same client.
+2


source to share


2 answers


There's a lot going on here. There are two parts to your question (if I haven't missed anything).

  • How to redirect double click action to command in your ViewModel
  • How do I open the "workspace" in this example (the workspace is just a tab in this case).

How to double click a ListViewItem, MVVM style

There are several ways, but this question on SO summarizes it pretty well: Conducting a double click event from a WPF list item using MVVM

I personally use the behaviors provided by MarlonGrech, so I'll show you how:

<ListView 
      AlternationCount="2" 
      DataContext="{StaticResource CustomerGroups}"
      ...>
      <ListView.ItemContainerStyle>
           <Style TargetType="{x:Type ListViewItem}">
                <Setter Property="acb:CommandBehavior.Event"
                        Value="MouseDoubleClick" />
                <Setter Property="acb:CommandBehavior.Command"
                        Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}, Path=DataContext.EditCustomerCommand}" />
                <Setter Property="acb:CommandBehavior.CommandParameter"
                        Value="{Binding}" />
            </Style>
      </ListView.ItemContainerStyle>
</ListView>

      

This will be associated with your EditCustomerCommand (which will be the RelayCommand), which you will need to set up in the AllCustomersViewModel.

Add a new workspace

This is more difficult. You will notice that the MainWindowViewModel has an AddWorkspace, but we don't really have a reference to this ViewModel from the AllCustomersViewModel.

I decided that the best way to do this (for me) is to create another interface called "IWorkspaceCommands" that AllCustomersViewModel will use to create new workspaces. This basically contradicts the respondent's previous suggestion of the Messenger approach. If you prefer the Messenger approach, you can use that here.

MainWindowViewModel actually implements this and will pass itself when it creates the AllCustomersViewModel.



public interface IWorkspaceCommands
{
     void AddWorkspace(WorkspaceViewModel view);
}

      

And here is the main implementation of the interface. This includes checking to see if the view is open , as requested (really simple!):

#region IWorkspaceCommands Members

public void AddWorkspace(WorkspaceViewModel view)
{
    if (!Workspaces.Contains(view))
    {
        Workspaces.Add(view);
    }
    SetActiveWorkspace(view);
}

#endregion

      

And finally, here's what the RelayCommand I told you about in your AllCustomersViewModel (along with some constructor modifications):

IWorkspaceCommands _wsCommands;
public AllCustomersViewModel(CustomerRepository customerRepository, IWorkspaceCommands wsCommands)
{
    _wsCommands = wsCommands;
    EditCustomerCommand = new RelayCommand(EditCustomer);
    ...
}

public void EditCustomer(object customer)
{
    CustomerViewModel customerVM = customer as CustomerViewModel;
    _wsCommands.AddWorkspace(customerVM);

}

      

That's pretty much it. Since you are dealing with a reference to the same ViewModel that was used to create the AllCustomersViewModel, when you edit it in one screen, it updates in the other without an event or messaging (okay !, but probably not reliable enough).

There is a slight problem with the ComboBox which does not auto-select the value for the company / person, but this is left as an exercise for the reader.

As part of my package today I am including a fully functional demo at no extra charge. http://dl.getdropbox.com/u/376992/MvvmDemoApp.zip

Hope it helps,

Anderson

+3


source


Using Josh's MvvmFoundation , you can use Messenger to pass messages between ViewModels ...

I would do it something like this:

-1. Create an instance of Singleton Messenger that can be seen from anywhere in your application.

public class MyMessenger
{
   static Messenger _messenger;
   public static Messenger Messenger
   {
      get
      {
         if (_messenger == null)
            _messenger = new Messenger();
         return _messenger;
      }
   }
}

      

-2. Then, in your MainWindowViewModel, register for specific message notifications - you can easily define your own message types eg.

MyMessenger.Messenger.Register<ViewModelBase>("CreateNew", (param) =>
{
  DoWork(param); /* If memory serves, the MainWindowViewModel already has the logic to create a new CustomerViewModel and put it in your Workspaces collection... (which I think answers your second point)  */
});

      



-3. Finally, you need to "notify" this message from your original ViewModel,

just:

MyMessenger.Messenger.NotifyColleagues("CreateNew", new CustomerViewModel(customerNo));

      

Sorry - I can't remember the exact structure of the CustomerViewModel from my head, but I hope you get the idea :)

Hope this helps :) Ian

+3


source







All Articles