C
C#2y ago
Snitrxm

❔ WPF Change Views

Im trying to switch views with MVVM pattern
49 Replies
Snitrxm
SnitrxmOP2y ago
I created a NavigationStore to save the currentViewModel the problem is
public partial class MainViewModel : ViewModelBase
{
private readonly NavigationStore _navigationStore;

public ViewModelBase CurrentViewModel => _navigationStore.CurrentViewModel;

public MainViewModel(NavigationStore navigationStore)
{
_navigationStore = navigationStore;
}

public void OnCurrentViewModelChanged()
{
System.Diagnostics.Debug.WriteLine(CurrentViewModel); //ViewModels.AccountViewModel
OnPropertyChanged(nameof(CurrentViewModel));
}
}
public partial class MainViewModel : ViewModelBase
{
private readonly NavigationStore _navigationStore;

public ViewModelBase CurrentViewModel => _navigationStore.CurrentViewModel;

public MainViewModel(NavigationStore navigationStore)
{
_navigationStore = navigationStore;
}

public void OnCurrentViewModelChanged()
{
System.Diagnostics.Debug.WriteLine(CurrentViewModel); //ViewModels.AccountViewModel
OnPropertyChanged(nameof(CurrentViewModel));
}
}
Everything works fine until this part When the navigationStore calls the OnCurrentViewModelChanged() function The logs is right, shows the new view to be displayed but the function OnPropertyChanged does not make any change
Snitrxm
SnitrxmOP2y ago
Snitrxm
SnitrxmOP2y ago
Im binding this way
Pobiega
Pobiega2y ago
your code shown above doesnt include any OnPropertyChanged listeners nvm, hidden in the baseclass ofc
Snitrxm
SnitrxmOP2y ago
public class ViewModelBase : ObservableObject
{
}
public class ViewModelBase : ObservableObject
{
}
my base class extend the mvvm toolkit that already have the listener for OnPropertyChanged
bighugemassive3
what about if you try binding directly to the _navigationStore's CurrentViewModel? you'd have to make it public obviously...
Snitrxm
SnitrxmOP2y ago
what do you mean? ohh nevermind i got i think i cant do it, cuz my dataContext is set to the mainViewModel not to NavigationStore
bighugemassive3
public partial class MainViewModel : ViewModelBase
{
public NavigationStore NavigationStore { get; }

public MainViewModel(NavigationStore navigationStore)
{
NavigationStore = navigationStore;
}
}
public partial class MainViewModel : ViewModelBase
{
public NavigationStore NavigationStore { get; }

public MainViewModel(NavigationStore navigationStore)
{
NavigationStore = navigationStore;
}
}
and then
Pobiega
Pobiega2y ago
but mainViewModel has a navigation store in it.
bighugemassive3
{Binding NavigationStore.CurrentViewModel} If that doesn't work then try putting those data templates into the ContentControl's resources. Maybe it isn't finding them in your window for some reason?
Snitrxm
SnitrxmOP2y ago
when i initialize its blank now
bighugemassive3
In your window put d:DataContext="{d:DesignInstance MainViewModel}" so that you can see any binding errors then you won't get those 3 dotted lines under some binding expressions ... unless the binding is invalid
Snitrxm
SnitrxmOP2y ago
<Grid>
<ContentControl Content="{Binding NavigationStore.CurrentViewModel}" />
</Grid>
<Grid>
<ContentControl Content="{Binding NavigationStore.CurrentViewModel}" />
</Grid>
It works the same ways as before okk
bighugemassive3
Also try moving those data templates into the ContentControl's resources instead it might not be finding the windows' resources for some reason If that still doesn't work then maybe you aren't even setting the windows' data context somehow?
Snitrxm
SnitrxmOP2y ago
sry, but i dont get it, what do u mean with ContentCOntrol's resources, im kinda new in wpf
bighugemassive3
In your window you have Window.Resources, and anything inside that, are resources that the window and any of its children have access too
Snitrxm
SnitrxmOP2y ago
I do
bighugemassive3
But the ContentControl might not be able to access them for some reason, so replace the content control with
<ContentControl Content="{Binding NavigationStore.CurrentViewModel}">
<ContentControl.Resources>
... data templates here
</ContentControl.Resources>
</ContentControl>
<ContentControl Content="{Binding NavigationStore.CurrentViewModel}">
<ContentControl.Resources>
... data templates here
</ContentControl.Resources>
</ContentControl>
If that also doesn't work then i'm not sure based on the code you provided
Snitrxm
SnitrxmOP2y ago
yeah doesnt work
bighugemassive3
Unless the DateTemplate types don't match up with the type that CurrentViewModel becomes that could also be a problem
Snitrxm
SnitrxmOP2y ago
as my experience, i thinks its a update in main windows problem
public void OnCurrentViewModelChanged()
{
System.Diagnostics.Debug.WriteLine(CurrentViewModel); //ViewModels.AccountViewModel
OnPropertyChanged(nameof(CurrentViewModel));
}
public void OnCurrentViewModelChanged()
{
System.Diagnostics.Debug.WriteLine(CurrentViewModel); //ViewModels.AccountViewModel
OnPropertyChanged(nameof(CurrentViewModel));
}
as I said this functions is called when a ViewModel is changed but the new viewModels does not update in .xaml
public class NavigationStore
{
public event Action CurrentViewModelChanged;
private ViewModelBase _currentViewModel;
public ViewModelBase CurrentViewModel
{
get => _currentViewModel;
set
{
_currentViewModel = value;
MainViewModel M = new(this);
M.OnCurrentViewModelChanged();
}
}
}
public class NavigationStore
{
public event Action CurrentViewModelChanged;
private ViewModelBase _currentViewModel;
public ViewModelBase CurrentViewModel
{
get => _currentViewModel;
set
{
_currentViewModel = value;
MainViewModel M = new(this);
M.OnCurrentViewModelChanged();
}
}
}
this is my class NavigationStore
bighugemassive3
Try changing ContentControl to ContentPresenter
Snitrxm
SnitrxmOP2y ago
I know that calling the function this way its bad I tried to do it with an event
bighugemassive3
I looked at one of my old projects and it uses ContentPresenter, but rarely ContentControl
Snitrxm
SnitrxmOP2y ago
but does not work ok doesnt work why its soo difficult to switching between views using mvvm pattern?
bighugemassive3
In your xaml are you still binding to CurrentViewModel or to NavigationStore.CurrentViewModel?
Snitrxm
SnitrxmOP2y ago
NavigationStore.CurrentViewModel
bighugemassive3
and you're using the MainViewModel code i provided?
Snitrxm
SnitrxmOP2y ago
yes
public partial class MainViewModel : ViewModelBase
{
public NavigationStore NavigationStore { get; }

public ViewModelBase CurrentViewModel => NavigationStore.CurrentViewModel;

public MainViewModel(NavigationStore navigationStore)
{
NavigationStore = navigationStore;
}

public void OnCurrentViewModelChanged()
{
System.Diagnostics.Debug.WriteLine(CurrentViewModel); //ViewModels.AccountViewModel
OnPropertyChanged(nameof(CurrentViewModel));
}
}
public partial class MainViewModel : ViewModelBase
{
public NavigationStore NavigationStore { get; }

public ViewModelBase CurrentViewModel => NavigationStore.CurrentViewModel;

public MainViewModel(NavigationStore navigationStore)
{
NavigationStore = navigationStore;
}

public void OnCurrentViewModelChanged()
{
System.Diagnostics.Debug.WriteLine(CurrentViewModel); //ViewModels.AccountViewModel
OnPropertyChanged(nameof(CurrentViewModel));
}
}
bighugemassive3
It's not working because you're creating a new instance of your MainViewModel each time the CurrentViewModel changes
public class NavigationStore
{
public event Action CurrentViewModelChanged;
private ViewModelBase _currentViewModel;
public ViewModelBase CurrentViewModel
{
get => _currentViewModel;
set
{
_currentViewModel = value;
OnPropertyChanged(nameof(CurrentViewModel));
}
}
}
public class NavigationStore
{
public event Action CurrentViewModelChanged;
private ViewModelBase _currentViewModel;
public ViewModelBase CurrentViewModel
{
get => _currentViewModel;
set
{
_currentViewModel = value;
OnPropertyChanged(nameof(CurrentViewModel));
}
}
}
if you use that instead, then it should work as long as your windows' data context is set to an instance of MainViewModel
Snitrxm
SnitrxmOP2y ago
does not work
public class NavigationStore : ViewModelBase
{
public event Action CurrentViewModelChanged;
private ViewModelBase _currentViewModel;
public ViewModelBase CurrentViewModel
{
get => _currentViewModel;
set
{
_currentViewModel = value;
OnPropertyChanged(nameof(CurrentViewModel));
}
}
}
public class NavigationStore : ViewModelBase
{
public event Action CurrentViewModelChanged;
private ViewModelBase _currentViewModel;
public ViewModelBase CurrentViewModel
{
get => _currentViewModel;
set
{
_currentViewModel = value;
OnPropertyChanged(nameof(CurrentViewModel));
}
}
}
i also added the
ViewModelbase
ViewModelbase
bighugemassive3
Are you sure your windows' DataContext is set to an instance of MainViewModel?
Snitrxm
SnitrxmOP2y ago
yeah
public partial class MainWindow : Window
{
NavigationStore navigationStore = new();

public MainWindow()
{
InitializeComponent();
navigationStore.CurrentViewModel = new HomeViewModel(navigationStore);
DataContext = new MainViewModel(navigationStore);
}
}
public partial class MainWindow : Window
{
NavigationStore navigationStore = new();

public MainWindow()
{
InitializeComponent();
navigationStore.CurrentViewModel = new HomeViewModel(navigationStore);
DataContext = new MainViewModel(navigationStore);
}
}
bighugemassive3
I dunno then... something must be wrong with your WPF install if binding doesn't work
Snitrxm
SnitrxmOP2y ago
do you have tutorial i that i can follow?
bighugemassive3
not really...
Snitrxm
SnitrxmOP2y ago
i tried a lot tutorials in yt nothin works
bighugemassive3
is your project on github?
Snitrxm
SnitrxmOP2y ago
i can put it to you take a look
bighugemassive3
if you do that then i can look
Snitrxm
SnitrxmOP2y ago
hold on a sec please
Snitrxm
SnitrxmOP2y ago
GitHub
GitHub - Snitrxm/ATM-System-MVVM
Contribute to Snitrxm/ATM-System-MVVM development by creating an account on GitHub.
Snitrxm
SnitrxmOP2y ago
here u go i'll appreciated a lot if you can take a look for me
bighugemassive3
In your HomeView and AccountView classes, remove the code where you're setting DataContext because the data context will already be set to HomeViewModel and AccountViewModel automaticall, because of how data templates work and then it should work after that
Snitrxm
SnitrxmOP2y ago
yeah its works i dunno why
bighugemassive3
wpf is spooky
Snitrxm
SnitrxmOP2y ago
thx a lot bro
bighugemassive3
np
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?