Navigation - WPF MVVM TUTORIAL #5

Поделиться
HTML-код
  • Опубликовано: 2 июн 2024
  • Learn about implementing navigation in an MVVM application. Navigation in WPF is implemented via a store, which is a single instance object that holds application state. The single navigation store is used throughout the application in order to update the current view.
    In this series, I demonstrate all the key components of a WPF MVVM application. This series will lay the foundations for building your own application.
    TIMESTAMPS:
    0:00 - Introduction
    0:47 - Implementing the NavigationStore
    3:17 - Mapping View Models to Views
    4:49 - Implementing the NavigateCommand
    5:45 - Notifying CurrentViewModel Changes
    7:06 - Abstracting the NavigateCommand
    10:15 - Implementing the NavigationService
    13:39 - Updating Reservation Listing Data
    15:04 - Conclusion
    NAVIGATION SERIES: • WPF Navigation
    SOURCE CODE: github.com/SingletonSean/rese...
    OTHER LINKS:
    Become a Member: / @singletonsean
    Donations: www.paypal.com/biz/fund?id=UB...
  • НаукаНаука

Комментарии • 73

  • @malcolmwhild2011
    @malcolmwhild2011 Год назад +3

    Hi Sean - just wanted to say thank you for this series. It's been really helpful for me, and I like your fast pace. I watch the video through first without trying to type any code. This gives me a high-level overview of what we're going to do. Then I use pause heaps as I type the code, and finally watch it through again and add comments. Great stuff, and thanks again 🙂

  • @blackcaer5542
    @blackcaer5542 9 месяцев назад

    Great course, thank You for doing that!

  • @ZANES-YT
    @ZANES-YT 2 года назад +21

    Man this is so useful gotta admit thoe u are going a lil to fast throught that so I always watch these videos 2 times, I came from java so not 100 percent practised and familiar with c# syntax, thanks although

  • @AlexReflex
    @AlexReflex Год назад +2

    My brain literally hurts after this video^^. But well explained :)

    • @SingletonSean
      @SingletonSean  Год назад +1

      Agreed, it is complex! I'm looking forward to using the built-in navigation in .NET MAUI.

  • @anngo2743
    @anngo2743 10 месяцев назад

    Great video! Btw, how did you move the constructor to the end of the class? (at 2:55) Is it an auto-format setting in Visual Studio? I'm just curious to know.

  • @SirBenJamin_
    @SirBenJamin_ Год назад +1

    I've been using WPF for a while now and have to saw, Stores are a completely new thing to me! .. not sure if I have been living under a rock, but I have not heard of them. Can I ask where you learnt them from?

  • @HosniBoun
    @HosniBoun 2 года назад

    thank you bro for this useful content.

  • @philipfroeschl1415
    @philipfroeschl1415 Год назад +1

    Hey SingleTonSean,
    first of all Thank you very much for your tutorials. I implemented your navigation from Video #5 to my project. Afterwards i tried to implement also a Navigation bar, recommended in on of your other videos. But it seems you do it there slightly different.
    What do i have to do, to implement a navigation bar in this project ? I have the problem that only 1x Viewmodel is allowed at the same time. If I place the NavigationBarViewModel in the StartUp, it can only see the navbar, and its working for one click. Afterwards the other ViewModel is Loaded and i just see a non working navbar.
    Any Ideas ? Thank you very much in advance.
    BR Philip

  • @en_acorn
    @en_acorn Год назад

    Greate Video! just a question, is there a way to determine what User Control is currently on view?

  • @guselmur5510
    @guselmur5510 Год назад

    Hey, great stuff! But why do you not use INotifyPropertyChangened in your Stores? I do use it in nearly all my BackendClasses is there any Reason not to do that?

  • @MrSaydo17
    @MrSaydo17 2 года назад +2

    Good stuff man! I might be being paranoid, but I think that the event subscriptions will cause you some memory leaks since you are creating new view models each time you navigate.

    • @SingletonSean
      @SingletonSean  2 года назад

      Thanks Jackson! Which event subscriptions were you referring to?

  • @iancarr3923
    @iancarr3923 2 года назад

    Very useful. I am reviewing the approach in this series against using Prism.

    • @SingletonSean
      @SingletonSean  2 года назад

      Thanks Ian! I've heard lots of people have enjoyed Prism's navigation. I haven't tried Prism so I won't leave my opinion, although I've browsed the docs a bit 🤭

    • @iancarr3923
      @iancarr3923 2 года назад

      @@SingletonSean Any chance of a video demonstrating the use of DTO's please?

    • @SingletonSean
      @SingletonSean  2 года назад +1

      Hey Ian, I actually kind of demonstrate it in part 6 of this series. Specifically, I use a DTO to map reservations to the reservation database table. I typically use DTOs whenever interfacing with an external data source (databases, APIs, etc.).

    • @iancarr3923
      @iancarr3923 2 года назад

      @@SingletonSean Many thanks Sean!

  • @BarankoweGranie
    @BarankoweGranie Год назад +1

    Do you have any idea why my data in listing view model is not showing up since I changed from simple binding to Data Template?

  •  2 года назад

    Hi Sean! Can you develop the code to navigate from ListViewModel to DetailViewModel and back with Factories? I'm stuck because I'm facing cross dependency: A ListViewModel needs a NavigationService for the DetailViewModel, so in the NavigationService constructor I pass a DetailViewModelFactory as a parameter, which as a method to create a DetailViewModel.
    Since the DetailViewModel needs to navigate back to ListViewModel, I need to pass a NavigationService for the ListViewModel, so with a ListViewModelFactory which needs the NavigationService for the DetailViewModel that I'm trying to initalize fiirst... How would you solve this? Is it possible with constructor dependency? I hope it's clear, I'm italian native speaker ;) Thanks and keep it up!!!

  • @Maxvm
    @Maxvm 2 года назад +1

    Wondering how to put multiple views into one main view, however, on single page. With that I mean to create something like a dashboard, for example split screen into 4 parts and each part would be connected to a different view. Is it possible to pass multiple data contexts to the main view at once ?

    • @SingletonSean
      @SingletonSean  2 года назад

      Hey Maximvs, that's a good question! For that, I usually have a view (such as ) that is made up of many UI components (such as , , etc.). Then, I'd have a view model (such as DashboardViewModel) that contains view model properties for the items in the dashboard (such as DashboardItemViewModel1, etc.). Finally, I can set the DataContext on the DashboardItem UI components as a binding to the DashboardItemViewModels.
      I wish I had an example for this! Let me know if this helps.

  • @younesbelouche8966
    @younesbelouche8966 Год назад

    I did exactly like you did but my view isn't changing when I click the navigate button (the current view model changes but no navigation)

  • @m.preacher2829
    @m.preacher2829 Год назад

    Which deign pattern did u use? Factory? It is a little difficult for me as a beginner😢

  • @Jeremygrmn
    @Jeremygrmn 2 года назад +1

    When you create your functions to create view models, what is the benefit of passing the functions into the constructors of the VM's? Couldn't you create the function in the VM itself and pass that in?

    • @SingletonSean
      @SingletonSean  2 года назад

      Hey Jeremy! I'm not sure I fully grasp your question, but I prefer to pass things through constructors to try and keep things loosely coupled. That might not actually matter here, and the other idea you raised might be a better option. Which view model were you referring to?

  • @binarybotany3218
    @binarybotany3218 10 месяцев назад

    With all the prop drilling going on, I'm hoping on some IoC dependency injection in the next chapters :)

  • @MaximilianGe
    @MaximilianGe 2 года назад

    Is there any good reason to do not use builtin NavigationService and Pages if you want to make navigation/browser style application?

    • @SingletonSean
      @SingletonSean  2 года назад

      Hey Besik, I've never been on a project that uses the built-in browser style navigation. I think that navigation is specifically for browser style apps, so I think there's definitely a good reason to use it there.

  • @williamjordan3008
    @williamjordan3008 2 года назад +2

    Hi I am trying to navigate to two different viewmodels from a master viewmodel. but both buttons go to the same viewmodel. can you give a suggestion.

    • @tarekjrd75
      @tarekjrd75 2 года назад

      Me too .. Same Issue

  • @yuliarotbert4017
    @yuliarotbert4017 2 года назад

    Hi, Great tutorial but I have some problem here, I get two separate windows when I run the app - one window is the main window and the second is the reservation window.. what can be the problem?

    • @SingletonSean
      @SingletonSean  2 года назад

      Thanks Yulia! For that issue, simply go into your App.xaml and remove the property StartupUri="MainWindow.xaml"

  • @user-kw2qe5pg6p
    @user-kw2qe5pg6p 2 месяца назад

    Thank you

  • @yakinwissem8665
    @yakinwissem8665 2 года назад

    hello, i have a question, i have a button that doesn't belong to any of the Views, its outside it, but i want to bind it to another viewmodel, is it possible to do so? basically having buttons binding to a viewmodel and others to another viewmodel.

    • @SingletonSean
      @SingletonSean  2 года назад +1

      Hey Yakin! It might be possible somehow, but I'm not sure if it'd be a good idea. I think your view models should line up with the structure of your views. That said, I'd either build a view model for your view with the lonely button, or find a way to move the button into the view with the desired view model.

  • @ImNorm29
    @ImNorm29 2 года назад +14

    Sean - your content is good and you do a good job of explaining things, BUT you go WAY to fast. I have to pause the video so often to catch up typing, it's affecting the flow of how your audio and the teaching you're trying to accomplish.

  • @meddler55
    @meddler55 Год назад +1

    Do you have a plugin installed for automation code formatting? If so what's it called?

    • @SingletonSean
      @SingletonSean  Год назад +1

      Hi Meddler, I use XAML Styler. It's awesome!
      marketplace.visualstudio.com/items?itemName=TeamXavalon.XAMLStyler

    • @meddler55
      @meddler55 Год назад

      @@SingletonSean Thanks for that, and thank so much for your exceptional videos, they've been indispensable for me!

  • @Tiger_Tisen
    @Tiger_Tisen 2 года назад +5

    Hi Sean! At 9:49 you created two functions: CreateMakeReservationViewModel() and CreateReservationViewModel().
    However, To make the first ViewModel, you need to use the second function
    and at the same time, to make the second ViewModel, you need to use the first function.
    Doesn't this create a never ending loop? I'm so confused about how this works

    • @smoke12785
      @smoke12785 2 года назад +1

      if you follow the instances to the navigateCommand Execute function you can see that the other func(delegate) is only called when the Execute function is called( in other words , the other function is called when the make Reservation button or the Cancel one is pressed , thus creating a new ViewModel instance each time).

    • @ivandrofly
      @ivandrofly Год назад

    • @ivandrofly
      @ivandrofly Год назад

      @@smoke12785 Yup, we are not calling it right away!

    • @ivandrofly
      @ivandrofly Год назад

      The delegates/functions to create ViewModels are not being called right away

  • @schrankwand8020
    @schrankwand8020 2 года назад

    Hello. At 7:02 i get an error as my OnCurrentViewModelChanged() has to return Action instead of void somehow. Using .net core 3. Would be glad if you cuold help me!

    • @adelseaux
      @adelseaux 2 года назад +5

      You might set OnCurrentViewModelChanged() but you have to give pointer of the method only so remove the "()" after OnCurrentViewModelChanged.
      like : _navigationStore.CurrentViewModelChanged += OnCurrentViewModelChanged;

  • @acparks77
    @acparks77 8 месяцев назад

    Everything worked to this point but @ 4:48 Getting the following errors vms is undeclared namespace, vms not defined, ReservationListingViewModel & MakeReservationViewModel is not supported in a WPF project :(

  • @ytbTheogr
    @ytbTheogr Год назад +1

    Its crazy that you can handle all the inheritance thing in your brain so you can express that with code

  • @JaredCollierFoster
    @JaredCollierFoster Год назад

    "We want our View to be determined by whatever the current ViewModel value is..." So is this what is considered a ViewModel-first approach?

  • @sunshinaudubon2558
    @sunshinaudubon2558 2 года назад +1

    Can you make a tutorial, how to open new windows using mvvm pattern?

    • @sunshinaudubon2558
      @sunshinaudubon2558 2 года назад

      Your videos are great, and I really like it!

    • @SingletonSean
      @SingletonSean  2 года назад

      Thanks Sunshin! I think this tutorial might be helpful: ruclips.net/video/M8BAIq0yoy8/видео.html

  • @AliMohammed-hr4te
    @AliMohammed-hr4te 2 года назад

    I'm already member but I can't watch the members videos .. help please..

    • @SingletonSean
      @SingletonSean  2 года назад +1

      Hi Ali, you might have mixed up subscriptions vs. memberships. Being a member implies that you've purchased a monthly membership to the channel, as mentioned here: ruclips.net/channel/UC7X9mQ_XtTYWzr9Tf_NYcIgjoin
      If you're interested in joining and supporting the channel, that'd be great and you'll be able to see all the videos! If not, no worries, all the videos that are currently "members only" will eventually be released publicly.

    • @AliMohammed-hr4te
      @AliMohammed-hr4te 2 года назад

      @@SingletonSean Thank you very much sir for the answer.. and thanks again for your valuable efforts.. I wish you more progress..

  • @Val-vm6qu
    @Val-vm6qu 2 года назад

    I think I missed the GetAllReservations method somewherew along the way.... 14:25

    • @wvvwwwvvw
      @wvvwwwvvw 2 года назад

      It was there for sure, but it happened in episode 2:
      ruclips.net/video/UQOi48H_84s/видео.html
      The change is also present in the github repo:
      github.com/SingletonSean/reservoom/commit/36f7b9ed519489ebb9806e04229dd02693e8c90e#diff-a193a2120c87dad8c56b83b6aee117287f09b4fb4c2c98d42f76eec0d2dce85cL30

  • @WaahaidIWKY
    @WaahaidIWKY 2 года назад

    at 1:44 you said "we only want one we navigation store we don't want to instantiate this multiple times ", why do we not use static ?, this is been confusing me the whole navigation playlist, really appreciate the response ~ fellow noob here

    • @SingletonSean
      @SingletonSean  2 года назад +4

      Hey Iwky, that's a great question and I've actually gotten this question in another video! Overall, you could make it static, as long you're comfortable with the implications of static classes. This is my response from other comment threads:
      I've actually seen frameworks do this. I think we'd have to consider the drawbacks of static classes.
      1. We can't leverage polymorphism with static classes. In other words, static classes cannot implement an interface or extend a base class. For example, in my navigation series, I create a "ModalNavigationStore" that controls navigation in a modal. To promote reusability, I extract an "INavigationStore" interface that the NavigationStore and ModalNavigationStore both implement. If NavigationStore were static, it would not be able to implement this interface.
      2. After reading point #1, you're probably thinking: "how about we make it a Singleton, which can leverage polymorphism?" This is much more realistic, but this means that we could only have one NavigationStore instance. What if we wanted multiple NavigationStores so that we could have multiple "sections" of navigation in our application? We wouldn't be able to do this with our single NavigationStore instance. This issue also applies to a static NavigationStore.
      3. Lastly, I feel like unit testing is more difficult when depending on a static class. The static class causes tight coupling, and we can't mock the static class. Of course, not everyone team is big on unit testing, so this drawback might not apply to every application.
      Perhaps these limitations of static classes aren't an issue for your application. In fact, all of the points I just made could be interpreted as a YAGNI ("you ain't gonna need it"). However, even though an application might not suffer from these drawbacks, I still think it's worth putting in the extra 1% of effort to pass the NavigationStore around rather than making it static.
      Anyways, let me know if you have any questions about this Iwky. I hope this was helpful! Thanks for the question.

    • @WaahaidIWKY
      @WaahaidIWKY 2 года назад

      @@SingletonSean Thank you for explaining that sean

  • @CyrilBalmadres-tc4nr
    @CyrilBalmadres-tc4nr 10 месяцев назад

    How to get the source code for this video?

  • @user-ow6gy6xj5v
    @user-ow6gy6xj5v 7 месяцев назад

    Why? Window must be the root of the tree. Cannot add Window as a child of Visual

  • @im1in260m
    @im1in260m Год назад

    Great videos, but presented at Mach one!

  • @dm-oz9yd
    @dm-oz9yd Год назад

    I sorta get it, but.. what a cluster

  • @johnnatanromero4901
    @johnnatanromero4901 Год назад +1

    You know a lot but you do not explain concepts

  • @aharongina5226
    @aharongina5226 Год назад

    stated good but awful coding at the end, awful

    • @SingletonSean
      @SingletonSean  Год назад

      Hey Aharon - sorry about that. I'm interested if you'd want to expand on this. Anyways, I hope the core topics from this video are still valuable. Certainly implement or code this in a more elegant way if possible!

  • @nguyenhoan3218
    @nguyenhoan3218 2 года назад

    Hi, at 7:57 can I implement the Execute() method like this?
    public override void Execute(object? parameter)
    {
    if (_navigationStore.CurrentViewModel is ReservationListingViewModel)
    _navigationStore.CurrentViewModel = new MakeReservationViewModel(_hotel, _navigationStore);
    else if (_navigationStore.CurrentViewModel is MakeReservationViewModel)
    _navigationStore.CurrentViewModel = new ReservationListingViewModel(_hotel, _navigationStore);
    }
    I check if CurrentViewModel is of type ReservationListingViewModel or MakeReservationViewModel
    and then I reassign CurrentViewModel to the opposite instance. The app work perfectly and I think this way is very straightforward.:)

  • @RettogoNow
    @RettogoNow 2 года назад

    @SingletonSean Look over the issue below. I put my MainWindow.xaml back to exactly how it was at the start of this video (after taking a screenshot so I would have what I had before when the error was there) and then I tried again to follow. the one thing I did different than you did in your video was when I had the DataContext on the like you did at the start was the compiler wasn't like that so I took the advice on fixing that and it created the xmlns:viewmodels declaration for me along with a d: for a Data Context I'm not real sure what was going on in that but I went with it. Then, I changed where it put viewmodels as the namespace mapping to vms like you had it and I ultimately deleted the line where it added d: whatever. Then I went with what you did in the video and it works. I've compared now to the screenshot of what I had before and I haven't seen a difference. At this point, I'm just happy that it works and I can move forward so screw it. I probably will become a member based on how great your advice is. I like that you are a fan of decoupling and, judging from your replies to some of the comments below, you've obviously put some thought into why you did what you did. My first thought, for example (like the user lwky below), when you said "you only want one of these," was we're going to use a static class.... I'm not a big fan of static classes so I was took a second to organize my thoughts and how I was going to argue against you doing that in this comment... And lo and behold, you took that left turn on me and instantiated the thing in the app class without using static. I like your style!

    • @SingletonSean
      @SingletonSean  2 года назад

      Hey Madi, that is an interesting issue! You should be okay without specifying DataContext on the since WPF will pass down the DataContext automatically. I'm glad the solution in this video solved your issue!
      I completely agree with your take on static classes and traditional singletons. I've been on so many projects that relied on singletons and they were soooo difficult to maintain and track bugs in. Now with the "built-in" dependency injection since .NET Core, I'm hoping projects will lean more in the direction of decoupling apps!