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;
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
add a comment |
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
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
add a comment |
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
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
c# wpf xaml
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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;
///...
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
|
show 24 more comments
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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;
///...
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
|
show 24 more comments
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;
///...
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
|
show 24 more comments
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;
///...
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;
///...
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
|
show 24 more comments
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
|
show 24 more comments
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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