Předchozí díly:
- MVVM #1–Úvod
- MVVM #2–Příprava
Jestli vzpomínáte na předchozí díl, byl tam návrh naší aplikace, která se skládala z navigačního menu (GroupCommands), pracovního prostoru (Workspace) a nějakých “akčních” tlačítek.
Co by tedy naše navigačního menu (GroupCommands) mělo obsahovat? Měl by stačit pouze nějaký název a kolekce Commandů, kde každý Command vytvoří novou záložku. Prostě když si kliknu v navigačním menu na nějakou možnost, vytvoří se mi nová záložka a v pracovním prostoru se zobrazí příslušné data.
/// <summary>
/// Trida reprezentujici leve menu
/// </summary>
public sealed class GroupCommand
{
/// <summary>
/// Nazev skupiny
/// </summary>
public string GroupName { get; set; }
/// <summary>
/// Prikazy ktere se provedou po stisku navigacnich tlacitek
/// </summary>
public List<RelayCommand> Commands { get; set; }
}
GroupCommand jsme si definovali, ale je třeba vytvořit hlavní ViewModel, který bude mít na starost:
- zobrazení navigačního menu
- zobrazení dat v pracovním prostoru
- vytváření nový záložek
Vytvořme si tedy MainWindowViewModel:

Jak si můžete všimnout na obrázku výše, budeme potřebovat pouze kolekci GroupCommands (navigační menu), Workspaces (jednotlivé záložky), SelectedWorkspace (aktuální záložka) a SelectedWorkspaceCommands (“akční" tlačítka). Dále jsou zde ještě metody pro vytvoření či odebrání záložky a pro vytvoření obsluhy žádosti o uzavření záložky.
public class MainWindowViewModel : ViewModelBase
{
#region | Fields
private ObservableCollection<WorkspaceViewModel> _workspaces;
private WorkspaceViewModel _selectedWorkspace;
#endregion // Fields
#region | Commands
/// <summary>
/// Leve menu
/// </summary>
public List<GroupCommand> GroupCommands { get; set; }
public List<RelayCommand> SelectedWorkspaceCommands
{
get
{
// pokud neni oznacen workspace vrat prazdnou kolekci
if ( SelectedWorkspace == null )
return new List<RelayCommand>();
return SelectedWorkspace.Commands;
}
}
#endregion // Commands
#region | Workspaces
/// <summary>
/// Aktualni seznam Workspace-u
/// </summary>
public ObservableCollection<WorkspaceViewModel> Workspaces
{
get
{
if ( _workspaces == null )
{
_workspaces = new ObservableCollection<WorkspaceViewModel>();
_workspaces.CollectionChanged += this.OnWorkspacesChanged;
}
return _workspaces;
}
}
/// <summary>
/// Aktualne vybrany Workspace
/// </summary>
public WorkspaceViewModel SelectedWorkspace
{
get { return _selectedWorkspace; }
set
{
if ( _selectedWorkspace == value )
return;
_selectedWorkspace = value;
// posli notifikaci o zmene vlastnosti SelectedWorkspace
OnPropertyChanged(MethodBase.GetCurrentMethod());
OnPropertyChanged("SelectedWorkspaceCommands");
}
}
#endregion // Workspaces
#region | OnWorkspacesChanged
/// <summary>
/// Obsluha udalosti ObservableCollection(WorkspaceViewModelEx).CollectionChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// pri zmene workspace vytvorim obsluhu udalosti RequestClose
if ( e.NewItems != null && e.NewItems.Count != 0 )
foreach ( WorkspaceViewModel workspace in e.NewItems )
workspace.RequestClose += this.OnWorkspaceRequestClose;
if ( e.OldItems != null && e.OldItems.Count != 0 )
foreach ( WorkspaceViewModel workspace in e.OldItems )
workspace.RequestClose -= this.OnWorkspaceRequestClose;
}
#endregion // OnWorkspacesChanged
#region | OnWorkspaceRequestClose
/// <summary>
/// Obsluha udalosti WorkspaceViewModel.RequestClose
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void OnWorkspaceRequestClose(object sender, EventArgs e)
{
// odeberu uzavreny workspace
Workspaces.Remove(sender as WorkspaceViewModel);
}
#endregion // OnWorkspaceRequestClose
#region | AddWorkspace
/// <summary>
/// Prida workspace do seznamu workspace-u
/// </summary>
/// <param name="workspaceViewModel"></param>
public void AddWorkspace(WorkspaceViewModel workspaceViewModel)
{
Workspaces.Add(workspaceViewModel);
SelectedWorkspace = workspaceViewModel;
}
#endregion // AddWorkspace
}
Tak už máme MainWindowViewModel, ale nemáme k němu příslušné View. To ovšem napravíme příště.