[WPF] Aplikacja w jednym oknie, frameworki MMVM

[WPF] Aplikacja w jednym oknie, frameworki MMVM
lukaszek016
  • Rejestracja:około 9 lat
  • Ostatnio:ponad rok
  • Postów:249
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?

grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
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.

edytowany 4x, ostatnio: grzesiek51114
lukaszek016
  • Rejestracja:około 9 lat
  • Ostatnio:ponad rok
  • Postów:249
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ąć?

lukaszek016
  • Rejestracja:około 9 lat
  • Ostatnio:ponad rok
  • Postów:249
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.

neves
  • Rejestracja:ponad 21 lat
  • Ostatnio:około godziny
  • Lokalizacja:Kraków
  • Postów:1114
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.


grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
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.
edytowany 2x, ostatnio: grzesiek51114
lukaszek016
  • Rejestracja:około 9 lat
  • Ostatnio:ponad rok
  • Postów:249
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" ? ;)

grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
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).

lukaszek016
  • Rejestracja:około 9 lat
  • Ostatnio:ponad rok
  • Postów:249
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

UN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:3
0
  1. Możesz zbindować sobie jaki widok ma obecnie być wyświetlany:
Kopiuj
<ItemsControl ItemsSource="{Binding Path=CurrentView}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
</ItemsControl>
MA
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 2 lata
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.
edytowany 1x, ostatnio: macastefan
lukaszek016
  • Rejestracja:około 9 lat
  • Ostatnio:ponad rok
  • Postów:249
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.

mr-owl
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad rok
  • Postów:206
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

edytowany 1x, ostatnio: mr-owl
lukaszek016
  • Rejestracja:około 9 lat
  • Ostatnio:ponad rok
  • Postów:249
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.

mr-owl
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad rok
  • Postów:206
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

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)