C
C#16mo ago
Snitrxm

❔ WPF Change Views

Im trying to switch views with MVVM pattern
49 Replies
Snitrxm
SnitrxmOP16mo 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
SnitrxmOP16mo ago
Snitrxm
SnitrxmOP16mo ago
Im binding this way
Pobiega
Pobiega16mo ago
your code shown above doesnt include any OnPropertyChanged listeners nvm, hidden in the baseclass ofc
Snitrxm
SnitrxmOP16mo ago
public class ViewModelBase : ObservableObject
{
}
public class ViewModelBase : ObservableObject
{
}
my base class extend the mvvm toolkit that already have the listener for OnPropertyChanged
br4kejet
br4kejet16mo ago
what about if you try binding directly to the _navigationStore's CurrentViewModel? you'd have to make it public obviously...
Snitrxm
SnitrxmOP16mo 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
br4kejet
br4kejet16mo ago
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
Pobiega16mo ago
but mainViewModel has a navigation store in it.
br4kejet
br4kejet16mo ago
{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
SnitrxmOP16mo ago
when i initialize its blank now
br4kejet
br4kejet16mo ago
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
SnitrxmOP16mo ago
<Grid>
<ContentControl Content="{Binding NavigationStore.CurrentViewModel}" />
</Grid>
<Grid>
<ContentControl Content="{Binding NavigationStore.CurrentViewModel}" />
</Grid>
It works the same ways as before okk
br4kejet
br4kejet16mo ago
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
SnitrxmOP16mo ago
sry, but i dont get it, what do u mean with ContentCOntrol's resources, im kinda new in wpf
br4kejet
br4kejet16mo ago
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
SnitrxmOP16mo ago
I do
br4kejet
br4kejet16mo ago
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
SnitrxmOP16mo ago
yeah doesnt work
br4kejet
br4kejet16mo ago
Unless the DateTemplate types don't match up with the type that CurrentViewModel becomes that could also be a problem
Snitrxm
SnitrxmOP16mo 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
br4kejet
br4kejet16mo ago
Try changing ContentControl to ContentPresenter
Snitrxm
SnitrxmOP16mo ago
I know that calling the function this way its bad I tried to do it with an event
br4kejet
br4kejet16mo ago
I looked at one of my old projects and it uses ContentPresenter, but rarely ContentControl
Snitrxm
SnitrxmOP16mo ago
but does not work ok doesnt work why its soo difficult to switching between views using mvvm pattern?
br4kejet
br4kejet16mo ago
In your xaml are you still binding to CurrentViewModel or to NavigationStore.CurrentViewModel?
Snitrxm
SnitrxmOP16mo ago
NavigationStore.CurrentViewModel
br4kejet
br4kejet16mo ago
and you're using the MainViewModel code i provided?
Snitrxm
SnitrxmOP16mo 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));
}
}
br4kejet
br4kejet16mo ago
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
SnitrxmOP16mo 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
br4kejet
br4kejet16mo ago
Are you sure your windows' DataContext is set to an instance of MainViewModel?
Snitrxm
SnitrxmOP16mo 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);
}
}
br4kejet
br4kejet16mo ago
I dunno then... something must be wrong with your WPF install if binding doesn't work
Snitrxm
SnitrxmOP16mo ago
do you have tutorial i that i can follow?
br4kejet
br4kejet16mo ago
not really...
Snitrxm
SnitrxmOP16mo ago
i tried a lot tutorials in yt nothin works
br4kejet
br4kejet16mo ago
is your project on github?
Snitrxm
SnitrxmOP16mo ago
i can put it to you take a look
br4kejet
br4kejet16mo ago
if you do that then i can look
Snitrxm
SnitrxmOP16mo ago
hold on a sec please
Snitrxm
SnitrxmOP16mo ago
GitHub
GitHub - Snitrxm/ATM-System-MVVM
Contribute to Snitrxm/ATM-System-MVVM development by creating an account on GitHub.
Snitrxm
SnitrxmOP16mo ago
here u go i'll appreciated a lot if you can take a look for me
br4kejet
br4kejet16mo ago
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
SnitrxmOP16mo ago
yeah its works i dunno why
br4kejet
br4kejet16mo ago
wpf is spooky
Snitrxm
SnitrxmOP16mo ago
thx a lot bro
br4kejet
br4kejet16mo ago
np
Accord
Accord16mo 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.
Want results from more Discord servers?
Add your server