• Nem Talált Eredményt

Konverterek

In document .NET-es programozási technológiák (Pldal 119-122)

Az előző példában nem könnyű észrevenni a WPF egy rejtett szolgáltatását, mégpedig az automatikus konverziót bizonyos típusú adatok között. Mint tudjuk, a TextBox.Text tulajdonság sztring típusú, míg a Slider.Value double. Igen kényelmes, hogy az ilyenfajta magától értetődő konverziókról nem a programozónak kell gondoskodnia.

Vannak azonban esetek, mikor a megfelelő konverzió nem ennyire magától értetődő, illetve jó, hogy ha a WPF lehetőséget ad az adatkonverzió testre szabására. Egy egyszerű példa: egy német cégnek készítünk egy nyilvántartó programot, melyben egy áru árát (Product.Price) double-ként tároljuk, de megjeleníteni a német árformátum szerint akarjuk (azaz két tizedes jegyre kerekítve és az ezreseket csoportosítva). Ehhez először is létre kell hoznunk egy saját konvertert – azaz egy új osztályt (pl. PriceConverter néven), aminek kötelezően az IValueConverter interfészt kell implementálnia (a System.Windows.Data névtérből).

class PriceConverter : IValueConverter {

public object Convert(object value, Type targetType, object parameter,

System.Globalization.CultureInfo culture) {

double price = (double)value;

return price.ToString("c", culture);

}

public object ConvertBack(object value, Type targetType, object parameter,

System.Globalization.CultureInfo culture) forrásadat átalakítására szolgál, míg a ConvertBack a céladatéra. A konvertálandó adatot a metódusok a value paraméterükben kapják meg; mivel mindkét metódusnak kellőképpen általánosan használhatónak kell lenni, a value object típusú, és ezért mindig konvertálnunk kell az általunk várt típusra. Mivel a forrásadatunk (Product.Price) most double típusú lesz, ezért a Convert elején double-re konvertáljuk a value-t; illetve a ConvertBack-ben sztringgé, hiszen a céladat (TextBox.Text) sztring típusú lesz.

A Convert végén a double értéket az árfomátumnak megfelelően megformázzuk. Ehhez a legegyszerűbb a .NET megfelelő szolgáltatását igénybe vennünk, mégpedig azt, hogy a ToString metódus egyik paraméterében

lehetséges egy formátumsztringet is megadnunk. A c formátumsztring1 ebben az esetben „currency”-t, azaz pénznemet jelöl, és hatására a kiírandó adat a rendszerbeállításoktól függően formázódik az adott nyelvben, illetve régióban honos szabályoknak megfelelően. Azaz ha pl. magyar nyelvű Windows-t használunk, akkor a magyarországi szabályok szerint. Hogyan lehet az alkalmazásunkat rávenni, hogy pl. a német szabályok szerint formázza az árat? Ehhez használhatjuk a GUI elemnek (mint az adatkötés célobjektumának) a Language attribútumát, mely az adott nyelv/régió megadására szolgál, és melyet most de-re állítunk2. Az adatkötés XAML-ben ennek megfelelően a következőképpen néz ki:

<TextBox Language="de">

<TextBox.Text>

<Binding Source="{x:Static Member=my:Product.prodToSale}" Path="Price">

<Binding.Converter>

A fenti példában a Binding-et nem jelölőnyelvi bővítmény segítségével írtuk fel, okkal. A magyarázata ennek az, hogy a PriceConverter osztályunkból létre kell hoznunk egy példányt, és ez az XML-tagként való szerepeltetésével automatikusan megtörténik. Mindesetre a fenti forráskód legalább azt is demonstrálja, hogyan használhatunk adatkötést a hagyományos módon. Ha mégis jelölőnyelvi bővítményt szeretnénk használni, akkor érdemes az irodalomban leginkább felkapott megoldáshoz folyamodni: a formunkhoz vagy az alkalmazásunkhoz erőforrásként hozzáadni egy PriceConverter példányt, és később erre az egy példányra hivatkozni mindenhonnan, ahol PriceConverter-re van szükségünk.

<Window.Resources>

<my:PriceConverter x:Key="priceConverterObject"/>

</Window.Resources>

Egy összetett példa. A Hiba: A hivatkozás forrása nem található. ábrán látható formot szeretnénk megvalósítani.

Egy ListBox-ban kutyafajták neveire kattintva a hozzájuk tartozó képet akarjuk megjeleníteni a lent található Image-ben. Egy szép megoldás az, ha létrehozunk egy Dog osztályt az egyes kutyafajták reprezentálására;

legyen ennek az osztálynak egy Name és egy ImageName tulajdonsága. A példa kedvéért létrehozunk egy Dog.dogs statikus listát, amibe manuálisan belepakolunk pár kutyafajtát.

class Dog

1 A lehetséges formátumsztringekből rengeteg van, ezekről referenciát, tananyagot az internet bőven nyújt, pl. http://msdn.microsoft.com/en-us/library/26etazsy.

2 Az egyes nyelvek/régiók kódjai fellelhetők az interneten, pl. http://msdn.microsoft.com/en-us/goglobal/bb896001.aspx. A magyar nyelv kódja a hu-HU, az amerikai angolé az en-US.

{

public string Name { set; get; } public string ImageName { set; get; }

public static List<Dog> dogs = new List<Dog> {

new Dog { Name="Berni pásztor", ImageName="berni.jpg" }, new Dog { Name="Csivava", ImageName="csivava.jpg" }, new Dog { Name="Dán dog", ImageName="dandog.jpg" }, new Dog { Name="Komondor", ImageName="komondor.jpg" } };

}

A hozzájuk tartozó képeket a lefordított program mellé az images könyvtárba rakjuk.

XIII.2. Adatkötés ListBox és Image között

Első lépésként összekötjük a Dog.dogs listát a ListBox-unkkal, a lenti XAML-kód 5. sorában látható módon. A listavezérlők ItemSource és DisplayMemberPath attribútumairól majd a következő fejezetben fogunk részletesebben értekezni; jelen pillanatban a lényeg az, hogy a ListBox a Dog.dogs listából nyeri az elemeit, melyeknek a Name tulajdonságát jeleníti meg.

<Window.Resources>

<my:DogToImageConverter x:Key="dogConverterObject"/>

</Window.Resources>

...

<ListBox Name="dogListBox"

ItemsSource="{x:Static my:Dog.dogs}" DisplayMemberPath="Name"/>

<Image Source="{Binding célja ImageSource típusú. A konverterünket a következőképpen írjuk meg:

class DogToImageConverter : IValueConverter {

public object Convert(object value, Type targetType, object parameter,

System.Globalization.CultureInfo culture)

public object ConvertBack(object value, Type targetType, object parameter,

System.Globalization.CultureInfo culture) {

throw new NotImplementedException();

}

}

Mint látható, a value paraméterben megkapott Dog objektumunkat „konvertáljuk” át egy BitmapImage objektummá oly módon, hogy az elérési útvonalában összefűzzük az aktuális könyvtárat az images könyvtárnévvel és a Dog objektumhoz tartozó képfájl nevével. Mint látható, a visszafelé való konverziót már nem tesszük lehetővé; ebből következően az Image-hez tartozó levő adatkötésben akár a Mode=OneWay-t is szerepeltethettük volna.

In document .NET-es programozási technológiák (Pldal 119-122)