WPF MVVM Navigation
-
I am using a composition of some different code samples to try to work with a WPF (MVVM) application. I started with Josh Smith's multiple view workspace model as below (pertinent snippet)
#region workspaces
public ObservableCollection<WorkspaceViewModel> Workspaces { get { if (\_workspaces == null) { \_workspaces = new ObservableCollection<WorkspaceViewModel>(); \_workspaces.CollectionChanged += OnWorkspacesChanged; } return \_workspaces; } } private void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.NewItems != null && e.NewItems.Count != 0) foreach (WorkspaceViewModel workspace in e.NewItems) workspace.RequestClose += OnWorkspaceRequestClose; if (e.OldItems != null && e.OldItems.Count != 0) foreach (WorkspaceViewModel workspace in e.OldItems) workspace.RequestClose -= OnWorkspaceRequestClose; } private void OnWorkspaceRequestClose(Object sender, EventArgs e) { var workspace = sender as WorkspaceViewModel; if (workspace != null) { workspace.Dispose(); Workspaces.Remove(workspace); } } #endregion #region private helpers private void DisplayAllFoo() { var workspace = Workspaces.FirstOrDefault(vm => vm is AllFooViewModel) as AllFooViewModel; if (workspace == null) { workspace = new AllFooViewModel(); Workspaces.Add(workspace); } SetActiveWorkspace(workspace); } private static void DisplayFoo() { } public void SetActiveWorkspace(WorkspaceViewModel workspace) { Debug.Assert(Workspaces.Contains(workspace)); var collectionView = CollectionViewSource.GetDefaultView(Workspaces); if (collectionView != null) collectionView.MoveCurrentTo(workspace); } #endregion
So it is easy enough to work with that, XAML code produces a list of commands which point to the voids above. I wanted to use a treeview navigation structure s
-
I am using a composition of some different code samples to try to work with a WPF (MVVM) application. I started with Josh Smith's multiple view workspace model as below (pertinent snippet)
#region workspaces
public ObservableCollection<WorkspaceViewModel> Workspaces { get { if (\_workspaces == null) { \_workspaces = new ObservableCollection<WorkspaceViewModel>(); \_workspaces.CollectionChanged += OnWorkspacesChanged; } return \_workspaces; } } private void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.NewItems != null && e.NewItems.Count != 0) foreach (WorkspaceViewModel workspace in e.NewItems) workspace.RequestClose += OnWorkspaceRequestClose; if (e.OldItems != null && e.OldItems.Count != 0) foreach (WorkspaceViewModel workspace in e.OldItems) workspace.RequestClose -= OnWorkspaceRequestClose; } private void OnWorkspaceRequestClose(Object sender, EventArgs e) { var workspace = sender as WorkspaceViewModel; if (workspace != null) { workspace.Dispose(); Workspaces.Remove(workspace); } } #endregion #region private helpers private void DisplayAllFoo() { var workspace = Workspaces.FirstOrDefault(vm => vm is AllFooViewModel) as AllFooViewModel; if (workspace == null) { workspace = new AllFooViewModel(); Workspaces.Add(workspace); } SetActiveWorkspace(workspace); } private static void DisplayFoo() { } public void SetActiveWorkspace(WorkspaceViewModel workspace) { Debug.Assert(Workspaces.Contains(workspace)); var collectionView = CollectionViewSource.GetDefaultView(Workspaces); if (collectionView != null) collectionView.MoveCurrentTo(workspace); } #endregion
So it is easy enough to work with that, XAML code produces a list of commands which point to the voids above. I wanted to use a treeview navigation structure s
I don't know whether I get your requirement correctly but try this, Create a static instance in the MainWindowViewModel and use MainWindowViewModel.Instance.MethodName() for accessing the method.
Arun Jacob My Technical Blog : Code.NET
-
I am using a composition of some different code samples to try to work with a WPF (MVVM) application. I started with Josh Smith's multiple view workspace model as below (pertinent snippet)
#region workspaces
public ObservableCollection<WorkspaceViewModel> Workspaces { get { if (\_workspaces == null) { \_workspaces = new ObservableCollection<WorkspaceViewModel>(); \_workspaces.CollectionChanged += OnWorkspacesChanged; } return \_workspaces; } } private void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.NewItems != null && e.NewItems.Count != 0) foreach (WorkspaceViewModel workspace in e.NewItems) workspace.RequestClose += OnWorkspaceRequestClose; if (e.OldItems != null && e.OldItems.Count != 0) foreach (WorkspaceViewModel workspace in e.OldItems) workspace.RequestClose -= OnWorkspaceRequestClose; } private void OnWorkspaceRequestClose(Object sender, EventArgs e) { var workspace = sender as WorkspaceViewModel; if (workspace != null) { workspace.Dispose(); Workspaces.Remove(workspace); } } #endregion #region private helpers private void DisplayAllFoo() { var workspace = Workspaces.FirstOrDefault(vm => vm is AllFooViewModel) as AllFooViewModel; if (workspace == null) { workspace = new AllFooViewModel(); Workspaces.Add(workspace); } SetActiveWorkspace(workspace); } private static void DisplayFoo() { } public void SetActiveWorkspace(WorkspaceViewModel workspace) { Debug.Assert(Workspaces.Contains(workspace)); var collectionView = CollectionViewSource.GetDefaultView(Workspaces); if (collectionView != null) collectionView.MoveCurrentTo(workspace); } #endregion
So it is easy enough to work with that, XAML code produces a list of commands which point to the voids above. I wanted to use a treeview navigation structure s
A common way to do this is to use something like a mediator (or the Messenger class in Laurent Bugnion's excellent MVVMLight framework). Basically you register a listener for each command in the MainWindowViewModel and then raise the appropriate command in the NavigationCommand VM - the listener will then react to it.
I have CDO, it's OCD with the letters in the right order; just as they ruddy well should be
Forgive your enemies - it messes with their heads
-
A common way to do this is to use something like a mediator (or the Messenger class in Laurent Bugnion's excellent MVVMLight framework). Basically you register a listener for each command in the MainWindowViewModel and then raise the appropriate command in the NavigationCommand VM - the listener will then react to it.
I have CDO, it's OCD with the letters in the right order; just as they ruddy well should be
Forgive your enemies - it messes with their heads
I think my fundamental problem is that I am not sure how to work with one viewmodel from another. Here is the breakdown. Mainwindow has a data context of Main Window View Model. The command to add and set active workspace resides on this view model. On the mainwindow there is a custom user control treeview that has a data context of navigationcategory view model. Within the treeview each bottom level node is a hyperlink. The binding for each command for each hyperlink is bound to the navigationcommand view model. With that said, the command on the navigation control view model needs to do something to add a new workspace and change the active work space on the main window view model. So the question is, what does the command look like on the navigation command view model to tell the main window view model to add a new workspace (based on whatever item is chosen on the treeview)
-
I think my fundamental problem is that I am not sure how to work with one viewmodel from another. Here is the breakdown. Mainwindow has a data context of Main Window View Model. The command to add and set active workspace resides on this view model. On the mainwindow there is a custom user control treeview that has a data context of navigationcategory view model. Within the treeview each bottom level node is a hyperlink. The binding for each command for each hyperlink is bound to the navigationcommand view model. With that said, the command on the navigation control view model needs to do something to add a new workspace and change the active work space on the main window view model. So the question is, what does the command look like on the navigation command view model to tell the main window view model to add a new workspace (based on whatever item is chosen on the treeview)
Solving this is easy if you have a workspace manager class (which would be a static instance) - then you simply call a method on this manager class to add a window to the workspace that belongs to the appropriate type.
I have CDO, it's OCD with the letters in the right order; just as they ruddy well should be
Forgive your enemies - it messes with their heads