The Setup
So I'm working on a project in which there exists a MainViewModel
class. This MainViewModel
contains a list of Soldiers
through an observable collection. I have a button in the MainView
which displays a new AddSoldierView
. The AddSoldierView
is binding to elements from the AddSoldierViewModel
. The AddSoldierView
is basically a form where the user inputs all of the data for that soldier.
The Problem
Now that I have the Soldier
's information on the AddSoldierViewModel
, I want to be able to add that back into the ObservableCollection of the MainViewModel
. I have binded a command to the button (Add Soldier) on the AddSoldierView
, but I'm not sure how to get that information back into the MainViewModel
.
What I've tried
I've already setting up an event handler on the AddSoldierViewModel
in which the SoldierModel
is passed as an EventArg. But I can't get the event itself to trigger.
Any suggestions? I've been trying to stay true to the MVVM spirit, but there are still some kinks I'm trying to sort out. Let me know if you want to see some code snippets, UML diagrams, or whatever.
AddSoldierViewModel.cs
public class AddSoldierViewModel : ViewModelBase
{
public event EventHandler<AddSoldierEventArgs> AddSoldierClicked;
public ICommand AddSoldierCommand;
private Soldier _soldier;
public Soldier Soldier
{
get => _soldier;
set
{
_soldier = value;
RaisePropertyChanged(nameof(Soldier));
}
}
public AddSoldierViewModel()
{
AddSoldierCommand = new RelayCommand(AddSoldier);
}
private void AddSoldier()
{
OnAddSoldierClicked(new AddSoldierEventArgs()
{
Soldier = Soldier
});
}
protected virtual void OnAddSoldierClicked(AddSoldierEventArgs e)
{
var handler = AddSoldierClicked;
handler?.Invoke(this, e);
}
}
MainViewModel.cs
public class MainViewModel : ViewModelBase
{
#region - Private Properties -
private Team _selectedTeam;
private Soldier _selectedSoldier;
#endregion // - Private Properties -
#region // - Public Properties -
public ObservableCollection<Soldier> Soldiers { get; set; }
public ObservableCollection<Team> Teams { get; }
public Team SelectedTeam
{
get => _selectedTeam;
set
{
_selectedTeam = value;
RaisePropertyChanged(nameof(SelectedTeam));
}
}
public Soldier SelectedSoldier
{
get => _selectedSoldier;
set
{
_selectedSoldier = value;
RaisePropertyChanged(nameof(SelectedSoldier));
}
}
#endregion // - Public Properties -
#region // - Commands -
public ICommand DeleteTeamCommand { get; private set; }
public ICommand AddSoldierDialogCommand { get; private set; }
#endregion // - Commands -
#region - Services -
public IDialogService AddSoldierDialogService { get; private set; }
#endregion // - Services -
#region - Constructors -
public MainViewModel()
{
Soldiers = new ObservableCollection<Soldier>();
Teams = new ObservableCollection<Team>();
Soldiers.CollectionChanged += Soldiers_CollectionChanged;
Teams.CollectionChanged += Teams_CollectionChanged;
DeleteTeamCommand = new RelayCommand(DeleteTeam);
AddSoldierDialogCommand = new RelayCommand(AddSoldierDialog);
AddSoldierDialogService = new AddSoldierDialogService();
}
#endregion // - Constructors -
#region - Methods -
private void AddSoldierDialog()
{
AddSoldierViewModel addSoldierViewModel = new AddSoldierViewModel();
addSoldierViewModel.AddSoldierClicked += AddSoldierViewModel_AddSoldierClicked;
AddSoldierDialogService.ShowDialog(addSoldierViewModel);
}
private void AddSoldierViewModel_AddSoldierClicked(object sender, AddSoldierEventArgs e)
{
Soldiers.Add(new Soldier(e.Soldier));
}
private void Teams_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
foreach (var item in e.NewItems)
{
}
foreach (var item in e.OldItems)
{
}
RaisePropertyChanged(nameof(Teams));
}
private void Soldiers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
foreach (var item in e.NewItems)
{
}
foreach (var item in e.OldItems)
{
}
RaisePropertyChanged(nameof(Soldiers));
}
#endregion // - Methods -
}
AddSoldierViewModel
which is binded to the button on the dialog. This command fires the event which is caught by theMainViewModel
, who then adds theSoldier
to the ObservableCollection.AddSoldierViewModel
side which controls theCanExecute()
of the RelayCommand.