WPF communication between multiple ViewModels



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








1















I'm currently working with a WPF application and has several problems. So far I've been putting all the business logic in a single ViewModel and what I noticed now is that ViewModel doesn't have a particular context.



An example would be:



 <telerik:RadSplitContainer Orientation="Vertical" telerik:DockingPanel.InitialSize="750,200">
<telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="200,300" >
<telerik:RadPane
<ContentControl ContentTemplate="StaticResource CategoryTemplate"
Content="Binding CategoryViewModel" />
</telerik:RadPane>
</telerik:RadPaneGroup>
<telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="100,120">
<telerik:RadPane Header="Items list"
CanUserClose="False" CanUserPin="False"
CanDockInDocumentHost="True">
<ContentControl ContentTemplate="StaticResource ItemsListTemplate"
Content="Binding ItemsViewModel" />
</telerik:RadPane>
</telerik:RadPaneGroup>
</telerik:RadSplitContainer>


However, this is how the mainwindows.xaml look like, which is built up by multiple views which is specified as a datatemplate. At this moment I decided to extract the business logic from the huge common viewmodel and create a ViewModel for each View.



I have two views, one for category and one for items corresponding to the category. These two views contain a gridview which show the categorys in CategoryView and Items corresponding to the category.



The viewmodel which contains all the items is at initial empty, and the category just retrieves all existing categories from DB. I also have a SelectedCategory in CategoryViewModel which contain the grid row item I choose.



The thing I want to do is at a selection of a row in the grid in categoryView, I want the CategoryViewModel to tell the ItemsViewModel to retrieve its items corresponding to the categoryID I'm retrieving from CategoryViewModel. Then refresh the itemscollection in the itemsViewModel with INotifyPropertychanged and refresh the view on the grid.



My mainView view and viewmodel:



 public MainViewModel()

this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();



public ViewModelBase CategoryViewModel

get return this._categoryViewModel;
set

if (this._categoryViewModel != value)

this._categoryViewModel = value;




public ViewModelBase ItemsViewModel

get

if (this._itemsViewModel == null)

this._itemsViewModel;

return this._itemsViewModel;

set

if (this._itemsViewModel != value)

this._itemsViewModel = value;





An example of another view datatemplate which is used in MainView:



<DataTemplate x:Key="NewsTemplate">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<telerik:RadBusyIndicator x:Name="BusyIndicator">
<telerik:RadGridView Name="gridView"
ItemsSource="Binding
Category"
SelectedItem="Binding SelectedCategory, Mode=TwoWay">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding=Binding Name" Header="Name"/>
</telerik:RadGridView>
</telerik:RadBusyIndicator>
</Grid>
</DataTemplate>`


Added viewmodel for items:



 public ObservableCollection<Item> GetItems

get

this._getItems = GetFromDb.GetItems(CategoryID)

return this._getItems;

set

if (this._getItems != value)

this._getItems = value;
this.OnPropertyChanged("GetItems");




public QueryableCollectionView Items

get

return this._items = new QueryableCollectionView(GetItems(CategoryID));

set

if (this._items != value)

this._items = value;
this.OnPropertyChanged(() => Items);





MainViewModel (if you look over I got a method GetFromDb.GetItems(CategoryID) which retrieves the items):



 public MainViewModel()

this.InitializeCommands();
this.CategoryViewModel = new CategoryViewModel();
this.ItemsViewModel = new ItemsViewModel();

this.CategoryViewModel.OnChanged += (s, e) =>

//this one?
this.ItemsViewModel.ContractMetaDatas(CategoryViewModel.ID)
//this one?
this.ItemsViewModel.ContractMetaDatas = new QueryableCollectionView(GetFromDb.GetItems(CategoryID));
;



How can I achieve this?










share|improve this question
























  • Are you using 1 view model per page?

    – Stefan
    Nov 15 '18 at 10:04











  • Hi @Stefan. Yes I'm using a viewmodel per view / page or rather component. I got a grid 1000x1000 which I have splitted into several regions containing different views / view resources. It's a onepage application with many views on the same page.

    – user6870932
    Nov 15 '18 at 10:29












  • Ok; assuming you have these viewmodel in some sort of container: define an event in the CategoryViewModel that the categoryID has changed (you can use the INotifyPropertyChanged's event for this but it is not ideal). Capture this in your container an pass it through to the ItemsViewModel.

    – Stefan
    Nov 15 '18 at 10:36

















1















I'm currently working with a WPF application and has several problems. So far I've been putting all the business logic in a single ViewModel and what I noticed now is that ViewModel doesn't have a particular context.



An example would be:



 <telerik:RadSplitContainer Orientation="Vertical" telerik:DockingPanel.InitialSize="750,200">
<telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="200,300" >
<telerik:RadPane
<ContentControl ContentTemplate="StaticResource CategoryTemplate"
Content="Binding CategoryViewModel" />
</telerik:RadPane>
</telerik:RadPaneGroup>
<telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="100,120">
<telerik:RadPane Header="Items list"
CanUserClose="False" CanUserPin="False"
CanDockInDocumentHost="True">
<ContentControl ContentTemplate="StaticResource ItemsListTemplate"
Content="Binding ItemsViewModel" />
</telerik:RadPane>
</telerik:RadPaneGroup>
</telerik:RadSplitContainer>


However, this is how the mainwindows.xaml look like, which is built up by multiple views which is specified as a datatemplate. At this moment I decided to extract the business logic from the huge common viewmodel and create a ViewModel for each View.



I have two views, one for category and one for items corresponding to the category. These two views contain a gridview which show the categorys in CategoryView and Items corresponding to the category.



The viewmodel which contains all the items is at initial empty, and the category just retrieves all existing categories from DB. I also have a SelectedCategory in CategoryViewModel which contain the grid row item I choose.



The thing I want to do is at a selection of a row in the grid in categoryView, I want the CategoryViewModel to tell the ItemsViewModel to retrieve its items corresponding to the categoryID I'm retrieving from CategoryViewModel. Then refresh the itemscollection in the itemsViewModel with INotifyPropertychanged and refresh the view on the grid.



My mainView view and viewmodel:



 public MainViewModel()

this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();



public ViewModelBase CategoryViewModel

get return this._categoryViewModel;
set

if (this._categoryViewModel != value)

this._categoryViewModel = value;




public ViewModelBase ItemsViewModel

get

if (this._itemsViewModel == null)

this._itemsViewModel;

return this._itemsViewModel;

set

if (this._itemsViewModel != value)

this._itemsViewModel = value;





An example of another view datatemplate which is used in MainView:



<DataTemplate x:Key="NewsTemplate">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<telerik:RadBusyIndicator x:Name="BusyIndicator">
<telerik:RadGridView Name="gridView"
ItemsSource="Binding
Category"
SelectedItem="Binding SelectedCategory, Mode=TwoWay">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding=Binding Name" Header="Name"/>
</telerik:RadGridView>
</telerik:RadBusyIndicator>
</Grid>
</DataTemplate>`


Added viewmodel for items:



 public ObservableCollection<Item> GetItems

get

this._getItems = GetFromDb.GetItems(CategoryID)

return this._getItems;

set

if (this._getItems != value)

this._getItems = value;
this.OnPropertyChanged("GetItems");




public QueryableCollectionView Items

get

return this._items = new QueryableCollectionView(GetItems(CategoryID));

set

if (this._items != value)

this._items = value;
this.OnPropertyChanged(() => Items);





MainViewModel (if you look over I got a method GetFromDb.GetItems(CategoryID) which retrieves the items):



 public MainViewModel()

this.InitializeCommands();
this.CategoryViewModel = new CategoryViewModel();
this.ItemsViewModel = new ItemsViewModel();

this.CategoryViewModel.OnChanged += (s, e) =>

//this one?
this.ItemsViewModel.ContractMetaDatas(CategoryViewModel.ID)
//this one?
this.ItemsViewModel.ContractMetaDatas = new QueryableCollectionView(GetFromDb.GetItems(CategoryID));
;



How can I achieve this?










share|improve this question
























  • Are you using 1 view model per page?

    – Stefan
    Nov 15 '18 at 10:04











  • Hi @Stefan. Yes I'm using a viewmodel per view / page or rather component. I got a grid 1000x1000 which I have splitted into several regions containing different views / view resources. It's a onepage application with many views on the same page.

    – user6870932
    Nov 15 '18 at 10:29












  • Ok; assuming you have these viewmodel in some sort of container: define an event in the CategoryViewModel that the categoryID has changed (you can use the INotifyPropertyChanged's event for this but it is not ideal). Capture this in your container an pass it through to the ItemsViewModel.

    – Stefan
    Nov 15 '18 at 10:36













1












1








1








I'm currently working with a WPF application and has several problems. So far I've been putting all the business logic in a single ViewModel and what I noticed now is that ViewModel doesn't have a particular context.



An example would be:



 <telerik:RadSplitContainer Orientation="Vertical" telerik:DockingPanel.InitialSize="750,200">
<telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="200,300" >
<telerik:RadPane
<ContentControl ContentTemplate="StaticResource CategoryTemplate"
Content="Binding CategoryViewModel" />
</telerik:RadPane>
</telerik:RadPaneGroup>
<telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="100,120">
<telerik:RadPane Header="Items list"
CanUserClose="False" CanUserPin="False"
CanDockInDocumentHost="True">
<ContentControl ContentTemplate="StaticResource ItemsListTemplate"
Content="Binding ItemsViewModel" />
</telerik:RadPane>
</telerik:RadPaneGroup>
</telerik:RadSplitContainer>


However, this is how the mainwindows.xaml look like, which is built up by multiple views which is specified as a datatemplate. At this moment I decided to extract the business logic from the huge common viewmodel and create a ViewModel for each View.



I have two views, one for category and one for items corresponding to the category. These two views contain a gridview which show the categorys in CategoryView and Items corresponding to the category.



The viewmodel which contains all the items is at initial empty, and the category just retrieves all existing categories from DB. I also have a SelectedCategory in CategoryViewModel which contain the grid row item I choose.



The thing I want to do is at a selection of a row in the grid in categoryView, I want the CategoryViewModel to tell the ItemsViewModel to retrieve its items corresponding to the categoryID I'm retrieving from CategoryViewModel. Then refresh the itemscollection in the itemsViewModel with INotifyPropertychanged and refresh the view on the grid.



My mainView view and viewmodel:



 public MainViewModel()

this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();



public ViewModelBase CategoryViewModel

get return this._categoryViewModel;
set

if (this._categoryViewModel != value)

this._categoryViewModel = value;




public ViewModelBase ItemsViewModel

get

if (this._itemsViewModel == null)

this._itemsViewModel;

return this._itemsViewModel;

set

if (this._itemsViewModel != value)

this._itemsViewModel = value;





An example of another view datatemplate which is used in MainView:



<DataTemplate x:Key="NewsTemplate">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<telerik:RadBusyIndicator x:Name="BusyIndicator">
<telerik:RadGridView Name="gridView"
ItemsSource="Binding
Category"
SelectedItem="Binding SelectedCategory, Mode=TwoWay">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding=Binding Name" Header="Name"/>
</telerik:RadGridView>
</telerik:RadBusyIndicator>
</Grid>
</DataTemplate>`


Added viewmodel for items:



 public ObservableCollection<Item> GetItems

get

this._getItems = GetFromDb.GetItems(CategoryID)

return this._getItems;

set

if (this._getItems != value)

this._getItems = value;
this.OnPropertyChanged("GetItems");




public QueryableCollectionView Items

get

return this._items = new QueryableCollectionView(GetItems(CategoryID));

set

if (this._items != value)

this._items = value;
this.OnPropertyChanged(() => Items);





MainViewModel (if you look over I got a method GetFromDb.GetItems(CategoryID) which retrieves the items):



 public MainViewModel()

this.InitializeCommands();
this.CategoryViewModel = new CategoryViewModel();
this.ItemsViewModel = new ItemsViewModel();

this.CategoryViewModel.OnChanged += (s, e) =>

//this one?
this.ItemsViewModel.ContractMetaDatas(CategoryViewModel.ID)
//this one?
this.ItemsViewModel.ContractMetaDatas = new QueryableCollectionView(GetFromDb.GetItems(CategoryID));
;



How can I achieve this?










share|improve this question
















I'm currently working with a WPF application and has several problems. So far I've been putting all the business logic in a single ViewModel and what I noticed now is that ViewModel doesn't have a particular context.



An example would be:



 <telerik:RadSplitContainer Orientation="Vertical" telerik:DockingPanel.InitialSize="750,200">
<telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="200,300" >
<telerik:RadPane
<ContentControl ContentTemplate="StaticResource CategoryTemplate"
Content="Binding CategoryViewModel" />
</telerik:RadPane>
</telerik:RadPaneGroup>
<telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="100,120">
<telerik:RadPane Header="Items list"
CanUserClose="False" CanUserPin="False"
CanDockInDocumentHost="True">
<ContentControl ContentTemplate="StaticResource ItemsListTemplate"
Content="Binding ItemsViewModel" />
</telerik:RadPane>
</telerik:RadPaneGroup>
</telerik:RadSplitContainer>


However, this is how the mainwindows.xaml look like, which is built up by multiple views which is specified as a datatemplate. At this moment I decided to extract the business logic from the huge common viewmodel and create a ViewModel for each View.



I have two views, one for category and one for items corresponding to the category. These two views contain a gridview which show the categorys in CategoryView and Items corresponding to the category.



The viewmodel which contains all the items is at initial empty, and the category just retrieves all existing categories from DB. I also have a SelectedCategory in CategoryViewModel which contain the grid row item I choose.



The thing I want to do is at a selection of a row in the grid in categoryView, I want the CategoryViewModel to tell the ItemsViewModel to retrieve its items corresponding to the categoryID I'm retrieving from CategoryViewModel. Then refresh the itemscollection in the itemsViewModel with INotifyPropertychanged and refresh the view on the grid.



My mainView view and viewmodel:



 public MainViewModel()

this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();



public ViewModelBase CategoryViewModel

get return this._categoryViewModel;
set

if (this._categoryViewModel != value)

this._categoryViewModel = value;




public ViewModelBase ItemsViewModel

get

if (this._itemsViewModel == null)

this._itemsViewModel;

return this._itemsViewModel;

set

if (this._itemsViewModel != value)

this._itemsViewModel = value;





An example of another view datatemplate which is used in MainView:



<DataTemplate x:Key="NewsTemplate">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<telerik:RadBusyIndicator x:Name="BusyIndicator">
<telerik:RadGridView Name="gridView"
ItemsSource="Binding
Category"
SelectedItem="Binding SelectedCategory, Mode=TwoWay">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding=Binding Name" Header="Name"/>
</telerik:RadGridView>
</telerik:RadBusyIndicator>
</Grid>
</DataTemplate>`


Added viewmodel for items:



 public ObservableCollection<Item> GetItems

get

this._getItems = GetFromDb.GetItems(CategoryID)

return this._getItems;

set

if (this._getItems != value)

this._getItems = value;
this.OnPropertyChanged("GetItems");




public QueryableCollectionView Items

get

return this._items = new QueryableCollectionView(GetItems(CategoryID));

set

if (this._items != value)

this._items = value;
this.OnPropertyChanged(() => Items);





MainViewModel (if you look over I got a method GetFromDb.GetItems(CategoryID) which retrieves the items):



 public MainViewModel()

this.InitializeCommands();
this.CategoryViewModel = new CategoryViewModel();
this.ItemsViewModel = new ItemsViewModel();

this.CategoryViewModel.OnChanged += (s, e) =>

//this one?
this.ItemsViewModel.ContractMetaDatas(CategoryViewModel.ID)
//this one?
this.ItemsViewModel.ContractMetaDatas = new QueryableCollectionView(GetFromDb.GetItems(CategoryID));
;



How can I achieve this?







c# wpf xaml






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 '18 at 13:26

























asked Nov 15 '18 at 10:00







user6870932



















  • Are you using 1 view model per page?

    – Stefan
    Nov 15 '18 at 10:04











  • Hi @Stefan. Yes I'm using a viewmodel per view / page or rather component. I got a grid 1000x1000 which I have splitted into several regions containing different views / view resources. It's a onepage application with many views on the same page.

    – user6870932
    Nov 15 '18 at 10:29












  • Ok; assuming you have these viewmodel in some sort of container: define an event in the CategoryViewModel that the categoryID has changed (you can use the INotifyPropertyChanged's event for this but it is not ideal). Capture this in your container an pass it through to the ItemsViewModel.

    – Stefan
    Nov 15 '18 at 10:36

















  • Are you using 1 view model per page?

    – Stefan
    Nov 15 '18 at 10:04











  • Hi @Stefan. Yes I'm using a viewmodel per view / page or rather component. I got a grid 1000x1000 which I have splitted into several regions containing different views / view resources. It's a onepage application with many views on the same page.

    – user6870932
    Nov 15 '18 at 10:29












  • Ok; assuming you have these viewmodel in some sort of container: define an event in the CategoryViewModel that the categoryID has changed (you can use the INotifyPropertyChanged's event for this but it is not ideal). Capture this in your container an pass it through to the ItemsViewModel.

    – Stefan
    Nov 15 '18 at 10:36
















Are you using 1 view model per page?

– Stefan
Nov 15 '18 at 10:04





Are you using 1 view model per page?

– Stefan
Nov 15 '18 at 10:04













Hi @Stefan. Yes I'm using a viewmodel per view / page or rather component. I got a grid 1000x1000 which I have splitted into several regions containing different views / view resources. It's a onepage application with many views on the same page.

– user6870932
Nov 15 '18 at 10:29






Hi @Stefan. Yes I'm using a viewmodel per view / page or rather component. I got a grid 1000x1000 which I have splitted into several regions containing different views / view resources. It's a onepage application with many views on the same page.

– user6870932
Nov 15 '18 at 10:29














Ok; assuming you have these viewmodel in some sort of container: define an event in the CategoryViewModel that the categoryID has changed (you can use the INotifyPropertyChanged's event for this but it is not ideal). Capture this in your container an pass it through to the ItemsViewModel.

– Stefan
Nov 15 '18 at 10:36





Ok; assuming you have these viewmodel in some sort of container: define an event in the CategoryViewModel that the categoryID has changed (you can use the INotifyPropertyChanged's event for this but it is not ideal). Capture this in your container an pass it through to the ItemsViewModel.

– Stefan
Nov 15 '18 at 10:36












1 Answer
1






active

oldest

votes


















0















The thing I want to do is at a selection of a row in the grid in categoryView, I want the CategoryViewModel to tell the ItemsViewModel to retrieve its items corresponding to the categoryID I'm retrieving from CategoryViewModel. Then refresh the itemscollection in the itemsViewModel with INotifyPropertychanged and refresh the view on the grid.



How can I achieve this?




Well, basically you can use a typical setup with events:



Fire an event from your CategoryViewModel and handle it in the overall container.



 public class MainViewModel: INotifyPropertyChanged

public CategoryViewModel CategoryViewModel get;set;
public ItemsViewModel ItemsViewModel get;set;

public MainViewModel()

this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();
//wire up the event
this.CategoryViewModel.OnChanged += (s,e) =>
//perform update here
this.ItemsViewModel.UpdateWithId(this.CategoryViewModel.SelectedId);
;


///...



The category:



public class CategoryViewModel : INotifyPropertyChanged

//fire this when appropiate
public event EventHandler OnChanged;
///...






share|improve this answer

























  • Thanks for reply, I would like to test your method but I'm having a couple question. //Perform update here , what logic would be inserted there? and what about the public YourMainViewModel(), would this be the constructor? Could you give me a realistic example when you actually update the ItemsViewModel upon change of SelectedCategory gets a value / changes?

    – user6870932
    Nov 15 '18 at 11:37












  • Updated it a bit: perform update means: update your data there. public YourMainViewModel()` is indeed a constructor, I altered it to your definition. I think this would be a realistic example based on the info you have given. I can get into more details but that would require more insights in your code.

    – Stefan
    Nov 15 '18 at 12:12











  • Thanks, I will try this. Do you know if your method works with async? By using private CategoryViewModel _categoryViewModel; the content doesn't recognize the view model, but by setting it to viewmodelbase, it works. Can I just use the view model base? private CategoryViewModel _categoryViewModel; private ViewModelBase _categoryViewModel; <ContentControl ContentTemplateSelector="StaticResource CategoryTemplate" Content="Binding CategoryViewModel" />

    – user6870932
    Nov 15 '18 at 12:23












  • Yes, you can do it like that; i hav made them public... the most important thing is the event. Define it and handle it. It shouln't impact the rest of your code.

    – Stefan
    Nov 15 '18 at 12:29











  • Hello, I've also updated the code in the thread. How does my ItemViewModel recieve the ID sent for MainViewmodel?

    – user6870932
    Nov 15 '18 at 12:47











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53316810%2fwpf-communication-between-multiple-viewmodels%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown
























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0















The thing I want to do is at a selection of a row in the grid in categoryView, I want the CategoryViewModel to tell the ItemsViewModel to retrieve its items corresponding to the categoryID I'm retrieving from CategoryViewModel. Then refresh the itemscollection in the itemsViewModel with INotifyPropertychanged and refresh the view on the grid.



How can I achieve this?




Well, basically you can use a typical setup with events:



Fire an event from your CategoryViewModel and handle it in the overall container.



 public class MainViewModel: INotifyPropertyChanged

public CategoryViewModel CategoryViewModel get;set;
public ItemsViewModel ItemsViewModel get;set;

public MainViewModel()

this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();
//wire up the event
this.CategoryViewModel.OnChanged += (s,e) =>
//perform update here
this.ItemsViewModel.UpdateWithId(this.CategoryViewModel.SelectedId);
;


///...



The category:



public class CategoryViewModel : INotifyPropertyChanged

//fire this when appropiate
public event EventHandler OnChanged;
///...






share|improve this answer

























  • Thanks for reply, I would like to test your method but I'm having a couple question. //Perform update here , what logic would be inserted there? and what about the public YourMainViewModel(), would this be the constructor? Could you give me a realistic example when you actually update the ItemsViewModel upon change of SelectedCategory gets a value / changes?

    – user6870932
    Nov 15 '18 at 11:37












  • Updated it a bit: perform update means: update your data there. public YourMainViewModel()` is indeed a constructor, I altered it to your definition. I think this would be a realistic example based on the info you have given. I can get into more details but that would require more insights in your code.

    – Stefan
    Nov 15 '18 at 12:12











  • Thanks, I will try this. Do you know if your method works with async? By using private CategoryViewModel _categoryViewModel; the content doesn't recognize the view model, but by setting it to viewmodelbase, it works. Can I just use the view model base? private CategoryViewModel _categoryViewModel; private ViewModelBase _categoryViewModel; <ContentControl ContentTemplateSelector="StaticResource CategoryTemplate" Content="Binding CategoryViewModel" />

    – user6870932
    Nov 15 '18 at 12:23












  • Yes, you can do it like that; i hav made them public... the most important thing is the event. Define it and handle it. It shouln't impact the rest of your code.

    – Stefan
    Nov 15 '18 at 12:29











  • Hello, I've also updated the code in the thread. How does my ItemViewModel recieve the ID sent for MainViewmodel?

    – user6870932
    Nov 15 '18 at 12:47















0















The thing I want to do is at a selection of a row in the grid in categoryView, I want the CategoryViewModel to tell the ItemsViewModel to retrieve its items corresponding to the categoryID I'm retrieving from CategoryViewModel. Then refresh the itemscollection in the itemsViewModel with INotifyPropertychanged and refresh the view on the grid.



How can I achieve this?




Well, basically you can use a typical setup with events:



Fire an event from your CategoryViewModel and handle it in the overall container.



 public class MainViewModel: INotifyPropertyChanged

public CategoryViewModel CategoryViewModel get;set;
public ItemsViewModel ItemsViewModel get;set;

public MainViewModel()

this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();
//wire up the event
this.CategoryViewModel.OnChanged += (s,e) =>
//perform update here
this.ItemsViewModel.UpdateWithId(this.CategoryViewModel.SelectedId);
;


///...



The category:



public class CategoryViewModel : INotifyPropertyChanged

//fire this when appropiate
public event EventHandler OnChanged;
///...






share|improve this answer

























  • Thanks for reply, I would like to test your method but I'm having a couple question. //Perform update here , what logic would be inserted there? and what about the public YourMainViewModel(), would this be the constructor? Could you give me a realistic example when you actually update the ItemsViewModel upon change of SelectedCategory gets a value / changes?

    – user6870932
    Nov 15 '18 at 11:37












  • Updated it a bit: perform update means: update your data there. public YourMainViewModel()` is indeed a constructor, I altered it to your definition. I think this would be a realistic example based on the info you have given. I can get into more details but that would require more insights in your code.

    – Stefan
    Nov 15 '18 at 12:12











  • Thanks, I will try this. Do you know if your method works with async? By using private CategoryViewModel _categoryViewModel; the content doesn't recognize the view model, but by setting it to viewmodelbase, it works. Can I just use the view model base? private CategoryViewModel _categoryViewModel; private ViewModelBase _categoryViewModel; <ContentControl ContentTemplateSelector="StaticResource CategoryTemplate" Content="Binding CategoryViewModel" />

    – user6870932
    Nov 15 '18 at 12:23












  • Yes, you can do it like that; i hav made them public... the most important thing is the event. Define it and handle it. It shouln't impact the rest of your code.

    – Stefan
    Nov 15 '18 at 12:29











  • Hello, I've also updated the code in the thread. How does my ItemViewModel recieve the ID sent for MainViewmodel?

    – user6870932
    Nov 15 '18 at 12:47













0












0








0








The thing I want to do is at a selection of a row in the grid in categoryView, I want the CategoryViewModel to tell the ItemsViewModel to retrieve its items corresponding to the categoryID I'm retrieving from CategoryViewModel. Then refresh the itemscollection in the itemsViewModel with INotifyPropertychanged and refresh the view on the grid.



How can I achieve this?




Well, basically you can use a typical setup with events:



Fire an event from your CategoryViewModel and handle it in the overall container.



 public class MainViewModel: INotifyPropertyChanged

public CategoryViewModel CategoryViewModel get;set;
public ItemsViewModel ItemsViewModel get;set;

public MainViewModel()

this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();
//wire up the event
this.CategoryViewModel.OnChanged += (s,e) =>
//perform update here
this.ItemsViewModel.UpdateWithId(this.CategoryViewModel.SelectedId);
;


///...



The category:



public class CategoryViewModel : INotifyPropertyChanged

//fire this when appropiate
public event EventHandler OnChanged;
///...






share|improve this answer
















The thing I want to do is at a selection of a row in the grid in categoryView, I want the CategoryViewModel to tell the ItemsViewModel to retrieve its items corresponding to the categoryID I'm retrieving from CategoryViewModel. Then refresh the itemscollection in the itemsViewModel with INotifyPropertychanged and refresh the view on the grid.



How can I achieve this?




Well, basically you can use a typical setup with events:



Fire an event from your CategoryViewModel and handle it in the overall container.



 public class MainViewModel: INotifyPropertyChanged

public CategoryViewModel CategoryViewModel get;set;
public ItemsViewModel ItemsViewModel get;set;

public MainViewModel()

this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();
//wire up the event
this.CategoryViewModel.OnChanged += (s,e) =>
//perform update here
this.ItemsViewModel.UpdateWithId(this.CategoryViewModel.SelectedId);
;


///...



The category:



public class CategoryViewModel : INotifyPropertyChanged

//fire this when appropiate
public event EventHandler OnChanged;
///...







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 15 '18 at 12:28

























answered Nov 15 '18 at 10:59









StefanStefan

8,65473862




8,65473862












  • Thanks for reply, I would like to test your method but I'm having a couple question. //Perform update here , what logic would be inserted there? and what about the public YourMainViewModel(), would this be the constructor? Could you give me a realistic example when you actually update the ItemsViewModel upon change of SelectedCategory gets a value / changes?

    – user6870932
    Nov 15 '18 at 11:37












  • Updated it a bit: perform update means: update your data there. public YourMainViewModel()` is indeed a constructor, I altered it to your definition. I think this would be a realistic example based on the info you have given. I can get into more details but that would require more insights in your code.

    – Stefan
    Nov 15 '18 at 12:12











  • Thanks, I will try this. Do you know if your method works with async? By using private CategoryViewModel _categoryViewModel; the content doesn't recognize the view model, but by setting it to viewmodelbase, it works. Can I just use the view model base? private CategoryViewModel _categoryViewModel; private ViewModelBase _categoryViewModel; <ContentControl ContentTemplateSelector="StaticResource CategoryTemplate" Content="Binding CategoryViewModel" />

    – user6870932
    Nov 15 '18 at 12:23












  • Yes, you can do it like that; i hav made them public... the most important thing is the event. Define it and handle it. It shouln't impact the rest of your code.

    – Stefan
    Nov 15 '18 at 12:29











  • Hello, I've also updated the code in the thread. How does my ItemViewModel recieve the ID sent for MainViewmodel?

    – user6870932
    Nov 15 '18 at 12:47

















  • Thanks for reply, I would like to test your method but I'm having a couple question. //Perform update here , what logic would be inserted there? and what about the public YourMainViewModel(), would this be the constructor? Could you give me a realistic example when you actually update the ItemsViewModel upon change of SelectedCategory gets a value / changes?

    – user6870932
    Nov 15 '18 at 11:37












  • Updated it a bit: perform update means: update your data there. public YourMainViewModel()` is indeed a constructor, I altered it to your definition. I think this would be a realistic example based on the info you have given. I can get into more details but that would require more insights in your code.

    – Stefan
    Nov 15 '18 at 12:12











  • Thanks, I will try this. Do you know if your method works with async? By using private CategoryViewModel _categoryViewModel; the content doesn't recognize the view model, but by setting it to viewmodelbase, it works. Can I just use the view model base? private CategoryViewModel _categoryViewModel; private ViewModelBase _categoryViewModel; <ContentControl ContentTemplateSelector="StaticResource CategoryTemplate" Content="Binding CategoryViewModel" />

    – user6870932
    Nov 15 '18 at 12:23












  • Yes, you can do it like that; i hav made them public... the most important thing is the event. Define it and handle it. It shouln't impact the rest of your code.

    – Stefan
    Nov 15 '18 at 12:29











  • Hello, I've also updated the code in the thread. How does my ItemViewModel recieve the ID sent for MainViewmodel?

    – user6870932
    Nov 15 '18 at 12:47
















Thanks for reply, I would like to test your method but I'm having a couple question. //Perform update here , what logic would be inserted there? and what about the public YourMainViewModel(), would this be the constructor? Could you give me a realistic example when you actually update the ItemsViewModel upon change of SelectedCategory gets a value / changes?

– user6870932
Nov 15 '18 at 11:37






Thanks for reply, I would like to test your method but I'm having a couple question. //Perform update here , what logic would be inserted there? and what about the public YourMainViewModel(), would this be the constructor? Could you give me a realistic example when you actually update the ItemsViewModel upon change of SelectedCategory gets a value / changes?

– user6870932
Nov 15 '18 at 11:37














Updated it a bit: perform update means: update your data there. public YourMainViewModel()` is indeed a constructor, I altered it to your definition. I think this would be a realistic example based on the info you have given. I can get into more details but that would require more insights in your code.

– Stefan
Nov 15 '18 at 12:12





Updated it a bit: perform update means: update your data there. public YourMainViewModel()` is indeed a constructor, I altered it to your definition. I think this would be a realistic example based on the info you have given. I can get into more details but that would require more insights in your code.

– Stefan
Nov 15 '18 at 12:12













Thanks, I will try this. Do you know if your method works with async? By using private CategoryViewModel _categoryViewModel; the content doesn't recognize the view model, but by setting it to viewmodelbase, it works. Can I just use the view model base? private CategoryViewModel _categoryViewModel; private ViewModelBase _categoryViewModel; <ContentControl ContentTemplateSelector="StaticResource CategoryTemplate" Content="Binding CategoryViewModel" />

– user6870932
Nov 15 '18 at 12:23






Thanks, I will try this. Do you know if your method works with async? By using private CategoryViewModel _categoryViewModel; the content doesn't recognize the view model, but by setting it to viewmodelbase, it works. Can I just use the view model base? private CategoryViewModel _categoryViewModel; private ViewModelBase _categoryViewModel; <ContentControl ContentTemplateSelector="StaticResource CategoryTemplate" Content="Binding CategoryViewModel" />

– user6870932
Nov 15 '18 at 12:23














Yes, you can do it like that; i hav made them public... the most important thing is the event. Define it and handle it. It shouln't impact the rest of your code.

– Stefan
Nov 15 '18 at 12:29





Yes, you can do it like that; i hav made them public... the most important thing is the event. Define it and handle it. It shouln't impact the rest of your code.

– Stefan
Nov 15 '18 at 12:29













Hello, I've also updated the code in the thread. How does my ItemViewModel recieve the ID sent for MainViewmodel?

– user6870932
Nov 15 '18 at 12:47





Hello, I've also updated the code in the thread. How does my ItemViewModel recieve the ID sent for MainViewmodel?

– user6870932
Nov 15 '18 at 12:47



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53316810%2fwpf-communication-between-multiple-viewmodels%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

Syphilis

Darth Vader #20