WPF i MEF – sterowanie wyglądem aplikacji w zależności od posiadanych zasobów.

Jednym z fundamentów WPF’a są zasoby – Resources
. Definiowane w ResourceDictionary
czyli słowniku zasobów. Każdy element słownika posiada swój klucz, który używamy do pobrania zasobu „z bazy”.
Odwołanie do zasobu może odbyć się na dwa sposoby.
StaticResource
– Wartość jest ustalona podczas załadowania XAML.DynamicResource
– Wartość jest ustalona w momencie, kiedy obiekt ma się pojawić.
To zachowanie DynamicResource możemy wykorzystać do wprowadzenia ciekawych rozwiązań.
Jeżeli DynamicResource
odwołuje się do zasobu aplikacji, to może być on przykryty przez inny zasób o tej samej nazwie.
Jeżeli mamy kilku klientów, a każdy z nich chce innych kolorów w swojej aplikacji, możemy załatwić tą prośbę dołączając do binarek .dll
z zasobami, które zmienią kolory w odpowiednich miejscach.
Przykładowa aplikacja ma na celu wyświetlać dwukolorową flagę.
Aplikacja zawiera swoje zasoby zdefiniowane w osobnej .DLL
o nazwach MainResources
(podstawowe zasoby aplikacji), ClientResources
(zasoby zmienione na danego klienta).
MainResources
Ten ResourceDictionary
zawiera coś, co nie każdy ResourceDictionary
posiada. Tym czymś jest klasa z code-behind.
Klasa służy do wprowadzenia atrybutów z frameworka MEF. Dzięki, któremu w łatwy sposób zaimportujemy słowniki zasobów do naszej aplikacji.
- Atrybut
[Export(typeof(ResourceDictionary))]
– upublicznia dla MEFa tą klasę. - Atrybut
[ExportMetadata("Order", 100)]
– to dodatkowe informacje o tej klasie,Order
wykorzystamy do posortowania naszych danych. Im coś ma większyOrder
to zostanie później wczytane do globalnego słownika zasobów, a to co później jest wczytywane to ma ważniejszą pozycję. To co zostanie wczytane jako ostatnie przykryje to co zostało wczytane wcześniej.
Client Resources
Słownik posiada zdefiniowane dwa klucze, które mają przykryć te z MainResources
.
Prawodopodobnie będziesz chciał pogmerać w .csproj
. Aby ustawić zależności kompilacji pliku AllStyles.xaml.cs
nad AllStyles.xaml
. By to zrobić musisz w pliku .csproj
znaleźć linijkę: <Compile Include="AllStyles.xaml.cs">
i zastąpić ją:
Dzięki czemu w widoku projektu pojawi się nam „graficzna reprezentacja zależności”.
Widok Aplikacji
Ładowanie wielu ResourceDictionary
Założenie jest takie, że assembly z zasobami są umieszczone w katalogu Resources
.
Potem dzięki słowniki, są sortowane przez wartość Order
i ładowane do głównego słownika aplikacji Application.Current.Resources
.
Pierwszy screenshot pokazał jak aplikacja wygląda jak w katalogu Resources
znajduje się tylko MainResources.dll
, poniżej znajduje się przykład w którym w katalogu Resources
są oba pliki MainResources.dll
i ClientResources.dll
.
Podsumowanie
Dzisiaj mogłeś się dowiedzieć:
- Można dodać klasę code-behind dla ResourceDictionary
- Możesz wykorzystać framework MEF do ładowania zasobów do aplikacji. W zależności czy są (czy nie) biblioteki z zasobami możesz zmieniać wygląd aplikacji.