WPF – Caliburn.Micro – Problemy podczas designu

Jeśli ktoś czytał moje poprzednie posty na temat MVVMa to z pewnością wie, że jednym z plusów jego stosowania jest możliwość odseparowania(w mniejszym lub większym zakresie) pracy programisty od pracy osoby odpowiedzialnej za design aplikacji. Oczywiście tak mówi teoria i często programista sam musi opracować wygląd okna aplikacji (no ale takie jest już życie). Wyobraźmy więc sobie, że dostaliśmy wytyczne jak ma wyglądać okno (takie a takie przyciski, tutaj grid, jakiś checkbox, szerokość elementu wynosząca tyle i tyle itp. itd.). Mając takie wytyczne możemy opracowywać View naszej aplikacji. Tylko jak sprawdzić czy spełniliśmy wymagania. Nie mamy przecież jeszcze podpiętej bazy (nie zapadły decyzję jak to będzie baza a może nie wiemy czy w ogóle będzie ona potrzebna) albo mamy, ale brak w niej danych. Co tu robić? Zawsze można zrobić jakiegoś fake (i to niezależnie od tego czy posiadamy bazę czy nie). Teraz tylko wystarczy zbuildować projekt i go uruchomić. Oczywiście powstają wtedy następujące problemy. Co w sytuacji gdy View nad którym pracujemy znajduje się głęboko w strukturze programu (trzeba “przeklikać” wiele okien) albo nie istniej któreś z pośrednich okien albo samo uruchomienie aplikacji trwa zbyt długo w stosunku do naszego zadania. Oczywiście możemy sobie poradzić z tymi problemami na różne sposoby (lepsze lub gorsze) ale to zawsze będą hacki, których czas wdrożenia (i późniejszego usunięcia) będzie niewspółmiernie długi do potrzeby. Jak więc podejść do tego inaczej?

Nie lubię być gołosłowny więc postanowiłem pokazać o co mi chodzi na przykładzie (tłumaczenie teorii zawsze wychodziło mi gorzej niż praktyczne zastosowanie).
Taka zagadka. Z jakimi kontrolkami mamy do czynienia na poniższym screenie (w celu uniknięcia niejasności screen pochodzi z designera)?
MasterDetailViewWithoutDesignTime
Jeśli ktoś tego nie wie to mamy tutaj StackPanel a w nim Grid (lewa strona) z danymi osobowymi i ListBox (prawa strona) z listą osób (dla niedowiarków kod dostępny pod tagiem MasterDetail).
Ten sam View po uruchomieniu
MasterDetailViewInApplication
Czyli aby zobaczyć czy widok wyświetli dane jak należy musimy uruchomić aplikację i przeklikać do odpowiedniego formularza. Zwykła strata czasu. Strata czasu, który mogliśmy poświęcić na coś innego. Po prostu okradanie pracodawcy. Jak więc zrobić to lepiej?

Caliburn.Micro

W Caliburn.Micro zrobienie tego jest proste. Po pierwsze potrzebujemy bezparametrowego konstruktora w ViemModel (w bardziej rozbudowanych przykładach aplikacji z wykorzystaniem CM nie jest to takie oczywiste, ale o tym w późniejszych częściach). W konstruktorze sprawdzamy czy aplikacja jest w Design Mode i jeśli to prawda to ustawiamy property naszego ViewModelu.

public MainWindowViewModel()
{
    if (Execute.InDesignMode)
        LoadFakeData();
}

Statyczna klasa Execute pochodzi z pakietu Caliburn.Micro.
Oczywiście to nie wszystko musimy w jakiś sposób poinformować nasz View skąd ma czerpać dane. Otóż w elemencie Window (UserControl, Page) musimy poczynić następujące wpisy:

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
mc:Ignorable="d"   
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro.Platform"  
xmlns:vm="clr-namespace:MVVM.ViewModels" 
d:DataContext="{d:DesignInstance Type=vm:MainWindowViewModel, IsDesignTimeCreatable=True}" 
cal:Bind.AtDesignTime="True"

Teraz zrozumiałe staje się dlaczego w VieWModelu potrzebujemy bezparametrowego konstruktora. A oto efekt naszych działań (kod dostępny pod tagiem DesignTimeData):
MasterDetailViewWithDesignTime
Wystarczy tylko zbuildować projekt i gotowe. Nie musimy uruchamiać aplikacji mamy wszystko gotowe (musimy tylko pamiętać o konieczności ponownego każdorazowego zbuildowania projektu po wprowadzeniu zmian).

Jeśli kogoś ciekawią inne sposoby na problemy z projektowaniem w Design Time to polecam wpis Iris Classon.

One thought on “WPF – Caliburn.Micro – Problemy podczas designu

  1. Pingback: dotnetomaniak.pl

Comments are closed.