• Nie Znaleziono Wyników

W WPF można wyróżnić dwa rodzaje zasobów:

Assembly resources (binary resources)

◦ pliki z danymi (binarne), wbudowane w skompilowany podzespół aplikacji (np.

obrazki)

działają prawie identycznie jak assembly resources w innych aplikacjach .NET, jedyną różnicą jest system adresujący, wykorzystywany przy odwoływaniu się od zasobów

zasobem typu assembly w aplikacjach WPF jest np. plik BAML (skompilowany plik XAML)

Object resources

◦ mogą być nimi dowolne obiekty, zdefiniowany przeważnie w XAMLu, umożliwiają przechowywanie różnego rodzaju informacji w centralnym miejscu, zapobiegając powtarzaniu kodu

Dodawanie zasobów typu assembly

• Należy dodać odpowiednie pliki do projektu i ustawić i właściwość Build Action na Resource (w celu lepszej organizacji, pliki mogą być grupowane w foldery).

Odwoływanie się do zasobów typu assembly

• Obiekt StreamResourceInfo daje dostęp m. in. do typu oraz strumienia danych zasobu:

StreamResourceInfo sri = Application.GetResourceStream(

new Uri("images/info.png", UriKind.Relative));

◦ ContentType zwraca string opisujący typ danych

◦ Stream – strumień (typu UnmanagedMemoryStream), z którego można odczytać bajty danych

• Niektóre klasy mają wbudowaną obsługę zasobów i potrafią z nimi współpracować (odnajdują je przez adres URI):

<Image Source="images/info.png" />

• lub:

image1.Source = new BitmapImage(

new Uri("images/info.png", UriKind.Relative));

Odwoływanie się do zasobów typu assembly

• Przez adres URI w przypadku zasobów zawartych w innym podzespole (bibliotece dll, z której korzysta nasza aplikacja):

img.Source = new BitmapImage(

new Uri("ImageLibrary;component/images/winter.jpg", UriKind.Relative));

Dodawanie zasobów z Build Action na Content (i Copy to Output Directory)

• Warto używać, gdy:

◦ chcemy zmieniać zasób bez ponownej kompilacji

◦ zasób jest bardzo duży

◦ plik jest opcjonalny i chcemy dostarczać aplikację również bez niego

◦ jest to plik dźwiękowy

• Content jest wygodniejsze, niż po prostu zwykłe dostarczenie plików z aplikacją i odczytywanie ich z dysku.

Object Resources

• Nowy system zasobów zintegrowany z XAML

• Możliwość definiowania zasobów w różnych miejscach (kontrolki, okna, cała aplikacja)

• Zasoby obiektowe (deklaratywne, logiczne):

◦ pozwalają na zdefiniowanie obiektu raz i używanie go w wielu miejscach kodu

◦ umożliwiają przeniesienie np. szczegółów formatujących kontrolek do centralnego miejsca, w którym mogą być w łatwy sposób zmieniane

◦ gdy pewna informacja jest oddzielona od reszty aplikacja, może być modyfikowana dynamicznie

Przykład wykorzystania Object resources definiowanie zasobu:

<Window.Resources>

<SolidColorBrush x:Key="zielony" Color="Green" />

</Window.Resources>

korzystanie z zasobu:

<Button Background="{StaticResource zielony}">

Statycznie

</Button>

<Button Background="{DynamicResource zielony}">

Dynamicznie

</Button>

Kolekcja zasobów

• Każdy element posiada właściwość Resources, która przechowuje kolekcję zasobów (ResourceDictionary)

• Kolekcja zasobów może przechowywać dowolne typy obiektów

• Przeważnie zasoby definiowane są na poziomie okna, gdyż wszystkie dzieci mają dostęp do zasobów ojca

Zasoby statyczne i dynamiczne

• Zasoby statyczne, w przeciwieństwie do dynamicznych, są pobierane raz (po deklaracji w kodzie XAML) i nie reagują na zmianę zasobu z poziomu kodu

this.Resources["zielony"] =

new SolidColorBrush(Colors.Yellow);

• Zasoby dynamiczne pobierane są za każdym razem, gdy są potrzebne. Ponieważ wiąże się to z dodatkowym narzutem, z zasobów dynamicznych należy korzystać tylko wtedy, gdy:

◦ zasób zależy od ustawień systemowych (np. kolory systemowe)

◦ planujemy podmieniać obiekty dynamicznie

Zasoby statyczne i dynamiczne

• Dlaczego jednak to działa?

SolidColorBrush brush =

(SolidColorBrush)this.Resources["zielony"];

brush.Color = Colors.Red;

• Ponieważ nie podmieniliśmy obiektu, a jedynie zmieniliśmy jego stan wewnętrzny.

Zaś Brush informuje każdą używającą go kontrolkę o swojej zmianie.

Techniki zaawansowane – zasoby niewspółdzielone

• Zazwyczaj powstaje jeden obiekt, z którego korzystają wszyscy używajacy tego zasobu.

• Możemy jednak udostępniać każdemu jego własny obiekt – można rozważać wykorzystanie tego, jeśli każdy użytkownik chce osobno modyfikować zasób lub zasobem jest coś, czego nie możemy dzielić (np. element) – są jednak lepsze sposoby by to osiągnąć.

<SolidColorBrush x:Key="TileBrush" x:Shared="False" ...>

</SolidColorBrush>

Techniki zaawansowane – dostęp do zasobów w kodzie

• W ten sposób mamy dostęp do zasobów zdefiniowanych w tej kontrolce:

Button cmd = (Button)sender;

Brush brush = (Brush)cmd.Resources["zielony"];

• Dzięki temu nie musimy znać położenia zasobu – nastąpi poszukiwanie, jak w wypadku korzystania z zasobu w XAMLu:

Brush brush = (Brush)cmd.FindResource("zielony");

Jest też TryFindResource(), które w razie niepowodzenia nie rzuca wyjątku, tylko zwraca null.

Zasoby aplikacji:

<Application ...>

<Application.Resources>

<SolidColorBrush x:Key="zielony" Color="Green" />

<SolidColorBrush x:Key="czerwony" Color="Red" />

<SolidColorBrush x:Key="niebieski" Color="Blue" />

</Application.Resources>

</Application>

• Są dostępne w całej aplikacji

◦ są trochę jak zmienne globalne: nie należy z nimi przesadzać

Jeszcze wyżej w drzewie poszukiwania znajdują się zasoby systemowe

Zasoby systemowe:

• Udostępniane są poprzez trzy klasy (przestrzeń nazw System.Windows):

SystemColors, SystemFonts, SystemParameters label.Foreground =

new SolidBrush(SystemColors.WindowTextColor);

• lub:

label.Foreground = SystemColors.WindowTextBrush;

• lub:

<Label Foreground="{x:Static SystemColors.WindowTextBrush}">

Napis

</Label>

• lub:

<Label Foreground="{DynamicResource

{x:Static SystemColors.WindowTextBrushKey}}">

Napis</Label>

Organizacja zasobów

• W celu umożliwienia współdzielenia zasobów między różnymi projektami tworzy się słowniki zasobów. Są one zapisywane w plikach XAML (dołączanych do aplikacji, z Build Action ustawionym na Page.

w pliku AppBrushes.xaml:

<ResourceDictionary ... >

<SolidColorBrush x:Key="zielony" Color="Green" />

<SolidColorBrush x:Key="czerwony" Color="Red" />

<SolidColorBrush x:Key="niebieski" Color="Blue" />

</ResourceDictionary>

Organizacja zasobów

• Następnie powinny być dołączone do jakiejś kolekcji zasobów w aplikacji.

<Application ... >

<Application.Resources>

<ResourceDictionary>

<ResourceDictionary.MergedDictionaries>

<ResourceDictionary Source="AppBrushes.xaml"/>

<ResourceDictionary Source="..."/>

</ResourceDictionary.MergedDictionaries>

<SolidColorBrush x:Key="inne zasoby" ... />

...

</ResourceDictionary>

</Application.Resources>

</Application>

Powiązane dokumenty