I have a window that displays templates in a tree, these can be selected which updates a ListView with available fields in the template. All related operations until here are managed by the TemplateViewModel declared at windows level as:
<Window.DataContext>
<vm:TemplateViewModel/>
</Window.DataContext>
extract of the class:
public class TemplateViewModel : ViewModelBase,INotifyPropertyChanged
{
public FieldTypeViewModel FieldTypeView { get; }
public TemplateViewModel()
{
// Create additional view
FieldTypeView = new FieldTypeViewModel(this);
...
}
Each template field has an identifier and type which are still managed by this view (all working up to here).
Now depending on the type of the field a different page is to be displayed in a reserved window part (Frame). Also the type view model is a separate view model class FieldTypeView . The FieldType object is created in the constructor of the TemplateViewModel and saved in the FieldTypeView property as it needs to be linked to this model for updating as field gets selected.
Both views used to implement the INotifyPropertyChanged interface but since the FieldTypeView is created by the view and not by the window defintion the notification event is not set, so I currently call the parent (TemplateViewModel) event for notification.
So I have a frame defined as:
<Frame DataContext="{Binding FieldTypeView}" Grid.Row="1" Content="{Binding CurrentFieldTypeSetupPage}"/>
public class FieldTypeViewModel : ViewModelBase
{
private TemplateViewModel _templateViewModel;
private TTemplateFieldType? _FieldType;
public TTemplateFieldType? FieldType
{
get { return _FieldType; }
set { _FieldType = value;
UpdateFieldType();
NotifyPropertyChanged("FieldType"); }
}
private Page? _CurrentFieldTypeSetupPage;
public Page? CurrentFieldTypeSetupPage
{
get { return _CurrentFieldTypeSetupPage; }
set { _CurrentFieldTypeSetupPage = value; NotifyPropertyChanged("CurrentFieldTypeSetupPage"); }
}
// Define property per type for easy data context access
public TTFTText? tfText { get; set; }
public TTFTDate? tfDate { get; set; }
//------------------------------------------------------------------------------
private void UpdateFieldType()
{
// Set the appropriate field type, and "null" the others
tfText = _FieldType as TTFTText;
tfDate = _FieldType as TTFTDate;
if (_FieldType != null)
{
CurrentFieldTypeSetupPage = _FieldType.GetSetupPage();
}
else
{
CurrentFieldTypeSetupPage = null;
}
}
//------------------------------------------------------------------------------
public void NotifyPropertyChanged(string prop)
{
_templateViewModel.NotifyPropertyChanged(prop);
}
//------------------------------------------------------------------------------
public FieldTypeViewModel(TemplateViewModel templateVM)
{
_templateViewModel = templateVM;
}
}
Every time the field selection changes the TemplateViewModel does set the FieldTypeView which gets the correct window for the current type and sets its CurrentFieldTypeSetupPage, which finally notifies the change via NotifyPropertyChanged("CurrentFieldTypeSetupPage"); which actually calls the TemplateViewModel's NotifyPropertyChanged method calling the event handler to notify the change.
Note that notification in the TemplateViewModel works for all its other fields, but the type page is never shown.
So the question is what I am doing wrong or what is the correct way to implement dynamic page changing in MVVM. My guess is that INotifyPropertyChange is not the correct way to go ?