2 Comments

Upravo sam potrošio 4 sata na traženje buga u jednoj Silverlight aplikaciji koju trenutno radim. Pošto sam na kraju ipak uspio pronaći u kojem zecu leži grm, i kako sam siguran da će netko osim mene doći do istog problema jer se radi o često korištenom obrascu ravzijanja, bilo bi dobro podjeliti ovaj mali tips&tricks koji može spasiti par sati uzaludnog traženja internetom (koje mene nije dovelo do rješenja ipak).

Bug izgleda ovako:

ovo je jedna kontrola u razvoju, i njezin zadatak je da ispisuje njezin status, dali je minimizirana i maksimizirana. To ispisuje ListBoxu, koji radi na sljedeći načim:

- na UserControl je postavljena DataContext klasa (MVVM pattern)
- ta ViewModel klasa ima jednu listu stringova definiranu kao ObservableCollection<string> property
- pomoći Binding sposobnosti, ažurirane vrijednosti u tom propertyu se automatski osvježavaju u ListBoxu, odnosno ispisuje lista tih stringova.
Primjer XAML deklaracije ListBoxa:


    
        
            
        
    


Bug je desi kada dodate više od 3-4 stringova u listu, i pokušate selektirati jednog, u ListBoxu će ostati selektirani, ili nasumično se selektirati više stavaka, kao što je prikazano u screenshotu (ListBox nema omogućeno selektiranje više od jedne stavke).. [more]
Ono što je zanimljivo, bug se ne pojavljuje ako NE koristite binding, nego napravite običnu List<string> i pridodjelite ju ItemsSource propertyu od ListBox-a!
Razlog ovoj pojavi mi je i dalje ostao nepoznat, pa ga mogu pripisati jedino mamurnom programeru u Microsoftovom razvojmom timu, nedostatku unit testiva, ili zbog urote Adobe/Apple inflitriranih agenata u Microsoftovim redovima. Ja bi se kladio na ovo zadnje.

Rješenje je jednostavno: na ListBox se mora bindati objekt, a ne string! Ha! Jednostavno rješenje, zar ne? A koje sve solucije sam pronašao na internetu, to je strašno, hackove koje ulaze u tamne dubine Silverlighta, gdje još programerova ruka nije kročila.
Naša ViewModel klasa sada nema property ObservableCollection<string>, nego ObservableCollection<StateItem>, gdje je StateItem klasa koja ima jedan string property StateName.


    
        
            
        
    

9 Comments

I konačno, prvi windaysi na kojima ći prisustvovati u cijelosti (ne ono: evo ti ulaznica na 2 sata, poslje mi vrati jer te zamjenjuje kolega), i to u velikome stilu; sa druge strane šanka! Odnosno speaker pulta ili kako se već to zove. Naime, pred par mjeseci sam prijavio nekoliko tema za prezentaciju, uglavnom vezanih za ASP.NET MVC i Silverlight, nakon čega je programski odbor konferencije slučajno izabrao jednu predloženu prezentaciju: Silverligh RIA Services!

Mali uvod u Silverlight RIA Services, počevši od uvoda u ADO.NET Astoriu, kasnije nazvanu ADO.NET Data Services, pa opet preimenovanu u WCF Data Services (marketing odjel si svašta dopušta izgleda). U osnovi, radi se o izlaganju REST sučelja, čime se omoguće pretraživanje podataka kreiranjem posebnog URLa, te operacija nad podacima upotrebom Http metoda Get, Post, Put i Delete.

Za razliku od "standardnog" web servis upita nad određenom metodom ili procedurom (RPC-nalik upiti), u RESTu nema izloženih metoda koje se mogu pozvati, nego se upiti provode nad (hijerarhiskim) modelom podataka. Kako to izgleda u praksi:

1. kreiramo bazu, postavimo relacije
2. mapiramo bazu na objekte pomoću nekog ORM alata (EF, nHibernate, ...)
3. REST frameworku (WCF data services / RIA Services) kažemo da želimo izložiti taj model podataka
4. Upitom "http://domena.com/wcfdataservis.svc/Categories/121/Products?filter=Price gt 100" dobijemo spisak proizvoda u kategoriji sa ID-om 121 koji imaju cijenu veću od 100. Svega nekoliko klikova i par linija koda konfiguracije izmjenjeno, vrlo jednostavno! Primjetite da URL sadrzi sam upit, odnosno “adresu” podataka koji zelimo, zajedno sa dodatnim filtrom. [more]

Kako sada Silverlight ulazi u tu priču? Naime, u Silverlightu možemo raditi upite (koji su uvjek asinkroni) nad web servisima, i Visual Studio se brine da kreira proxy klase koje obavljanju serijalizaciju/deserijalizaciju i omogućavaju stronly-type način rada. To je onaj “obični” način rada, old-school ;)

Pomoću RIA Services izlažemo metode koje vraćaju podatke, a iz Silverlighta možemo raditi LINQ upite nad tim podacima. LINQ upiti se serijaliziraju, enkodiraju u onaj REST URI upit, koji se na serveru potom ponovo deserijalizira u LINQ i izvršava nad podacima koje tražena metoda vraća. Uz to, RIA services se brine oko asinkronog dohvata apstrahirajući sam proces asinkronog pozivanja web servisa i podizanja evenata.

Plan za Windays prezentaciju je da napravim jednu relativno jednostavnu aplikaciju koja koristi RIA Services, poslovnu logiku drži na serveru, validacija je definirana nad entitetima domene, a Silverlight je isključivo prezentacijski klijent. Aplikacija će biti dostupa za slobodan download, a nadam se da ću neke njezine zanimljive dijelove obraditi i u par blog postova, kao naprimjer:

  • custom autorizacija i autentifikacija
  • izlaganje podataka preko RIA Data Services
  • MVVM pattern i RIA Services
  • validacija
  • navigacija unutar Silverlight aplikacije
  • pub/sub pattern za komunikaciju unutar Silverlight aplikacije (već opisano na ovom blogu)

Aplikacija će služiti za kreiranje putnih naloga. Proces kreiranja putnih naloga:

  • zaposlenik kreira zahtjev za odobrenjem naloga. Nalog sadrži osnovne podatke o destinaciji putovanja, relacijama, vremenu, vozilu
  • voditelj odobrava nalog ili ga vraća zaposleniku uz poruku
  • nakon povratka sa putovanja zaposlenik unosi troškove (prijeđene relacije, dane, dodatne troškove tunela, parkinga,…)
  • djelatnik računovodstva računa dnevnice i isplate prema unesenim podacima
  • printanje izvještaja
  • tablica raspoloživosti voznog parka

Vjerojatno veći dio ovih funkcionalnosti neće biti u potpunosti implementiran do Windaysa (u trenutku pisanja to je za 11 dana), ali nadam se s vremenom da će aplikacija doći do verzije 1!