[WPF] Aplikacja w jednym oknie, frameworki MMVM

0

Witam.

Mam kilka pytań co do aplikacji w WPF. Próbuję tworzyć aplikacje używając wzorca MVVM. Testowałem Prisma, MMVM Light, używałem biblioteki MahApps. Jednak właśnie nasywa mi się podczas tego kilka pytań.

  1. Aplikacja w jednym oknie. Nie chodzi mi tutaj, aby cała aplikacja była w jednym oknie, ale chciałbym mieć kilka widoków otwieranych w ramach jednego okna. Np. używając TabControl lub nawet jakiejś wstążki. Jeśli chodzi o TabControl mógłbym co prawda utworzyć TabItemy i w każdym jakiegoś grida, ale wtedy mój ViewModel byłby ogromny dla powiedzmy 10 zakładek. Jeśli chodzi o wstażkę to moja koncepcja to chyba klasycznie, na górze okna wstążka z przyciskami, a pod wstążką miejsce na widoki, które się wyświetlają po wybraniu odpowiedniej opcji na wstążce. Jak to ugryźć? Szczerze mówiąc to nawet nie wiem czego szukać.

  2. Frameworki MVVM. W sumie zastanawiam się, któy wybrać, na którym się skupić. Prism wydaje mi się bardziej przystępny, nie muszę rejestrować nowych ViewModeli. W MVVM Light za to jest Messeneger, który jest chyba łątwiejszy do opanowania niż EventAggegator w Prismie. Co do kontenerów IoC. W Prismie z template mogę sobie wybrać np. Autofac czy Unity, w MVVM Light mam SimpleIoC. Rozumiem, że mogę je stosować w oby frameworkach?

1

Jeśli chodzi o TabControl mógłbym co prawda utworzyć TabItemy i w każdym jakiegoś grida, ale wtedy mój ViewModel byłby ogromny dla powiedzmy 10 zakładek

Zawsze możesz wstawiać w TabItem obiekty UserControl gdzie każdy z takich obiektów ma swój osobny, własny viewmodel. Prosto i ładnie. Komunikować się mogą za pomocą np. event aggregatora. Pamiętać tylko należy o jednym: TabControl za każdym razem ładuje od nowa do pamięci swoje itemy podczas przełączania. Jest to o tyle kłopotliwe, że jeśli ktoś wypełni jakiś formularz i przełączy się na chwilkę na inną zakładkę to jego danych we wspomnianym formularzu już nie ma. Ot taki ficzer ;)

MVVM Light za to jest Messeneger, który jest chyba łątwiejszy do opanowania niż EventAggegator w Prismie

Zasada działania jest chyba nawet identyczna czyli oparte o wzorzec obserwatora eventy.

Rozumiem, że mogę je stosować w oby frameworkach?

Kontener IoC możesz sobie wybrać jakikolwiek.

0

Ok, dzięki za odpowiedzi ;)

Co do TabControl i "ulotności" jego danych, w sumie bardzo dobrze, przynajmniej nie trzeba "zerować" texboxów.

A co w przypadku, gdy zamiast TabControl używam czegoś innego? Np. zastanawiam się nad FluentRibbon. Na górze mam wstążkę, a nawet, żeby uprościć to można powiedzieć, że zwykłe menu z buttonów, a na dole wydzielone pole na xamle z własnymi viewmodelami, które ładowane są do okna po naciśnięciu przycisku. Mógłbyś mi podpowiedzieć jak to jakoś ogarnąć?

0

Ok, nie wiem czy o to chodzi, ale znalazłem taki tutorial:

https://www.codeproject.com/Articles/140613/WPF-Tutorial-Layout-Panels-Containers-Layout-Trans

Chodzi o pierwszy akapit z nawigacją. Tylko to jest zrobione poprzez code-behind, a ja bym chciał to ogarnąć ViewModelem.

Co prawda tu jest mowa a elementach Pages, nie wiem jednak czy ma to zastosowanie do aplikacji desktopowych czy tylko web.

Ewentualnie takie pojęcia jak Window Container, Form Container. Tylko nie mam pomysłu jak to rozwiązać i gdzie znaleźć jakieś informacje, przykłady.

1

Nie bój się używać codebehind do napisania infrastuktury, mvvm jest dla części biznesowej, infrastruktura która umożliwia stosowanie mvvm jak najbardziej moze być napisana przy uzyciu codebehind.

0

No to ja bym zrobił to tak: zrobiłbym viewmodel wyłącznie dla wstążki i wszelkie zmiany w oknie, które aktualnie jest obsługiwane rozgłaszałbym przez event aggregatora.

Czyli dajmy na to:

  • Wciskasz guzik na wstążce;
  • Event aggregator propaguje event, jeśli trzeba to przenosząc potrzebne dane;
  • Obserwatorzy, czyli viewmodele okien pod ribbonem, subskrybują eventy i odpowiednio obsługują po czym desubskrybują podczas unloadowania kontrolki.
0

Ok, ale zostaje jeszcze ViewModel okna, w którym umieszczona jest wstążka i kontener na okna wywoływane ze wstążki. On jest pusty? (ViewModel). W takim razie ViewModele okien otrzymują event, że został wywowałe i pojawiają się na, że tak powiem "scenie" ? ;)

0

Tak na dobrą sprawę takie okno może w ogóle nie posiadać viewmodelu, bo cała komunikacja odbywać się będzie pomiędzy wstążką, a jej kontenerem na okna (czy jak to tam jest zrobione, bo już kompletnie nie pamiętam).

0

Kurczę, a nie ma nigdzie nawet prostego, żeby mnie nakierować przykładu? ;) Przyznam szczerze, że to z ta propagacją eventów przez EventAggregator trochę mi w głowie pokręciło, bo zazwyczaj robiłem odwrotnie, czyli jakby w kontenerze na okienka tworzyłem nową instancję okna. A tutaj okno samo utworzy swój obiekt i "wskoczy" do kontenera. Ciężka sprawa szczerze mówiąc, muszę o tym pomyśleć, jak to rozgryźć. :P

0
  1. Możesz zbindować sobie jaki widok ma obecnie być wyświetlany:
<ItemsControl ItemsSource="{Binding Path=CurrentView}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
</ItemsControl>
0

a dlaczego by nie tak?:

  1. Glowny ViewModel zawierajacy ObservableCollection dla poszczegolnym viewmodeli w TabControl.
  2. Komunikacja miedzy poszczegolnymi viewmodelami jesli jest wymagana rozwiazania na poziemie Glownego ViewModela.
  3. Glowny ViewModel jako ItemsSource dla TabControl
  4. Poszczegolne Tab'y rozrozniane w DataType DataTemplate'a
  5. Jesli chcemy utrzymac stan miedzy przelaczaniem tabow, to UpdateSourceTrigger=PropertyChanged w DataTemplate TabControl.
0

W sumie postanowiłem wykorzystać Prisma i powoli ogarniam sobie moduły i regiony. Nie do końca widzę jeszcze zastosowanie modułów w mojej aplikacji, ale musiałem i tak utworzyć jeden do regionów. Teoretycznie działa ładowanie regionów do okna, jednak wrzucam do nich UserControl i męczę się póki co, aby w UserControl wrzucić całą Fluent Ribbon. No i do ogarnięcia EventAggregator.

0

A po co chcesz wrzucić Ribbona do głównego regionu, zrób sobie drugi widok który odpowiada tylko za aktualnego Ribbon-a i przełączając się pomiędzy widokami podmieniaj także zawartość Ribbon-a

mr-owl

P.S. Możliwe że będziesz musiał napisać CustomRegionAdapter

0

Tak właśnie zamierzałem zrobić. Stworzyć dwa regiony. NavigationRegion i tam wrzucić ribbona i ContentRegion dla głównej zawartości. Co do podmieniania zawartości ribbona to zostawię to na później. Póki co to chce aby odpowiednie buttony na ribbonie zmieniały mi główny content.

0

Witam,

Generalnie to konstruktor w klasie viewmodel powinien wyglądać tak:

public ShellViewModel(IDialogService dialogService, IEventAggregator eventAggregator, ILoggerFacade loggerFacade, IRegionManager regionManager){} IDialogService pochodzi z MvvmDialogs. I teraz w command masz
this.regionManager.RequestNavigate("MainRegion", new Uri($"TwójView", UriKind.RelativeOrAbsolute));. Nie zapomnij o tym że moduł musi być dodany do katalogu podczas startu aplikacji moduleCatalog.AddModule(typeof(DefaultModule));

Pozdrawiam,

mr-owl

1 użytkowników online, w tym zalogowanych: 0, gości: 1