XAML.cz Magazín moderních technologií založených na XAML

RAD aneb s Telerikem na výročí

Napsáno pro Silverlight od Leoš Urban [04.07.2011]

Můj první článek na XAML.CZ budu věnovat ukázce jednoduché, ale přesto reálně použitelné silverlightové aplikace pro evidenci důležitých výročí. Pro vývoj budeme využívat komerční komponenty RadControls společnosti Telerik a dotáhneme to až na internet. Vy si můžete pak tímto způsobem udělat evidenci knížek, dévédéček, známek,…

Pokud by někdo tápal nad zkratkou RAD – Rapid Application Development, tak je to metodologie pro rychlé, typicky „klikačské“ programování bez složitých příprav (typickým příkladem pro tyto postupy bylo Delphi).

Nuže do toho...

Nastartujeme si Visual Studio 2010, předpokládám že bude třeba verze Professional a výše, kde již máme nainstalován Silverlight 4, WCF.RIA Services podporu a knihovny Telerik RadControls for Silverlight (klidně trial). Mlčky také předpokládám, že na počítači je i nainstalována instance MS SQL Server 2008 Express Edition.

Nový projekt

Nyní založíme projekt Vyroci, který bude typu Silverlight, Silverlight Application. V následujícím dialogu zaškrtneme WCF RIA Services.

Vzniknou dva projekty: klientský projekt „Vyroci“ v Silverlightu a webový projekt „Vyroci.Web“.

VyrociProjekt1

Úložiště dat

Ve webovém projektu přidáme ASP.NET adresář App_Data (Add, New ASPNET Folder, App_Data ). V něm založíme novou databázi Add, New Item, SQL Server Database s názvem „Vyroci.mdf“. Vlevo se otevře ServerExplorer a je tam přidáno spojení na tuto databázi.

Rozklikneme databázi a v části Tables zvolíme Add New Table.

Id int not null (Identity Specification, Is Identity yes, 1,1 – nastavuje se v Column properties dole)
Datum date not null
Nazev nvarchar(100) not null
Popis nvarchar(MAX) nullable

Tip: je lepší mít názvy v 1. osobě jednotného čísla s velkým písmenem na začátku

Na Id klikneme pravým tlačítkem a vybereme „Set Primary Key“.

Tip: tabulka musí mít primární klíč.

Vybereme Save a pojmenujeme tabulku „Vyroci“.

Tip: není chytré mít název stejně jako některý sloupec a je lepší mít jej v 1. osobě jednotného čísla s velkým písmenem na začátku (aby se později názvy entit nemusely přemapovávat).

Tímto máme připravené úložiště.

Zdroj dat

Na webovém projektu založíme složku s názvem Models (Add, New Folder) a do ní přidáme konceptuální model EDMX pomocí Add, New Item, Data/ADO.NET Entity Data Model s názvem Vyroci.

Budeme generovat z databáze (Generate from Database), z databáze Vyroci s uložením údajů do Web.Config (Save Entity connection settings).

VyrociEdmx2

Vybereme všechny tabulky (zaškrtnout). Name space ponecháme na VyrociModel, zbytek neměníme a stiskneme Finish.

Výsledkem je EDMX model, kde akorát klikneme na Zmeneno a nastavíme Concurrency mode na Fixed.

VyrociEdmx4

Uložíme a přeložíme webový projekt.

Pamatuj: přeložení je nutné aby Visual Studio v dalším kroku našlo data.

Doménová služba

Na webovém projektu založíme složku s názvem Services (Add, New Folder) a do ní přidáme doménovou službu pomocí Add, New Item, Web/Domain Service Class s názvem VyrociDomainService.cs.

Zkontrolujeme vybraný zdroj dat na VyrociEntities, zaškrtneme generování tabulky (chcete-li, entity) Vyroci a povolíme její editovatelnost, generování metadat ponecháme zašktnuté.

VyrociDomainService1

 

Vznikne nám doménová služba s metodami:

public IQueryable GetVyroci()
public void InsertVyroci(Vyroci vyroci)
public void UpdateVyroci(Vyroci currentVyroci)
public void DeleteVyroci(Vyroci vyroci)

Webový projekt opět přeložíme, aby se pomocí tzv WCR RIA linku promítnuly změny do klientské části.

Tím máme vyřízenu serverou část.

Klient

 

Otevřeme si předgenerovaný formulář MainPage.xaml .

Do hlavičky přidáme jmenný  prostor na naší webovou službu:

xmlns:services="clr-namespace:Vyroci.Web"

V Toolboxu najdeme skupinu RadControls for Silverlight, najdeme kompoentu RadDomainDataSource a přetáhneme na plochu formuláře nebo do XAML. Jedná se o nevizuální komponentu, takže je stejně vidět jen v XAML. Do referencí jsou automaticky přidány odpovídající Telerik knihovny, do hlavičky XAML přidá jmenný prostor pro Telerik. Do XAML přibude řádek, který následně upravíme:

<telerik:RadDomainDataSource Name="radDomainDataSource1" AutoLoad="True" QueryName="GetVyroci"  LoadedData="radDomainDataSource1_LoadedData" SubmittedChanges="radDomainDataSource1_SubmittedChanges">
<telerik:RadDomainDataSource.DomainContext>
<services:VyrociDomainContext/>
telerik:RadDomainDataSource.DomainContext>
telerik:RadDomainDataSource>

Vlastnost AutoLoad znamená, že komponenta bude načítat data automaticky, bez explicitního volání metody Load(). Vlastnost QueryName říká, jaký zdroj dat v doménové službě se použije. Události LoadedData() a SubmittedChanges umožňují aplikaci reagovat na chybové stavy.

A pozor: záměna DomainContext za DataContext je oblíbený zádrhel jak mít syntakticky korektní nefunkčí aplikaci.

Do CodeBehind (klikněte F7) doplníme obsluhu události vyvolané po načtení dat. Pokud nastane chyba, bude zobrazen dialog.

private void radDomainDataSource1_LoadedData(object sender, Telerik.Windows.Controls.DomainServices.LoadedDataEventArgs e)
{
if (e.HasError)
{
MessageBox.Show(e.Error.Message);
e.MarkErrorAsHandled();
}
}

 

Do CodeBehind doplníme obsluhu události vyvolané po promítnutí změn.

private void radDomainDataSource1_SubmittedChanges(object sender, Telerik.Windows.Controls.DomainServices.DomainServiceSubmittedChangesEventArgs e)
{
if (e.HasError)
{
MessageBox.Show(e.Error.Message);
e.MarkErrorAsHandled();
}
}

 

Připravíme si detail, který bude zobrazován, pokud si jej uživatel vyžádá. Skládá se z jednoduchého formuláře se dvěma sloupci a čtyřmi řádky. Je umístěn v rámci Grid tagu.

<Grid.Resources>
<DataTemplate x:Key="detail">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="*" MinHeight="200"/>
Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Id"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Id}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Datum"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Datum, Mode=TwoWay, StringFormat=dd.MM.yyyy}" />
<TextBlock Grid.Row="2" Grid.Column="0" Text="Název"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Nazev, Mode=TwoWay}"/>
<TextBox Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding Popis, Mode=TwoWay}"  AcceptsReturn="True" />
Grid>
DataTemplate>
Grid.Resources>

 

Dále přetáhneme na formulář nebo XAML RadGridView a upravíme:


ItemsSource="{Binding DataView, ElementName=radDomainDataSource1}" 
ShowInsertRow="True" 
AutoGenerateColumns="False" 
AlternateRowBackground="Azure" AlternationCount="2"
RowDetailsTemplate="{StaticResource detail}" 
RowEditEnded="rgv_RowEditEnded"
Deleted="rgv_Deleted">


	DataMemberBinding="{Binding Id}" Width="100" 
	IsReadOnly="True"/>
	
	DataMemberBinding="{Binding Datum}" DataFormatString="d" 
	Width="150"/>
	
	DataMemberBinding="{Binding Nazev}" Width="*"/>
	
	

Vlastnost ItemsSource přebírá položky z RDDS k zobrazení. Vlastnost ShowInsertRow ukazuje nahoře prázdný řádek pro rychlé vložení. Vlastnost AutoGenerateColumns vypíná automatické generování sloupců, protože si je nastavíme explicitně. Vlastnosti AlternateRowBackground a AlternationCount nastavují barvu pozadí sudých řádků pro lepší odlišení. Konečně RowDetailTemplate určuje šablonu pro detail. Událost RowEditEnded je volána při ukončení editace řádku.

 

Doplníme obsluhu události vyvolané po ukončení editace řádku:

	private void RadGridView_RowEditEnded(object sender, Telerik.Windows.Controls.GridViewRowEditEndedEventArgs e)
	{
	radDomainDataSource1.SubmitChanges();
	}

Doplníme obsluhu události vyvolané po ukončení mazání řádku:

	
	private void rgv_Deleted(object sender, GridViewDeletedEventArgs e)
	{
	radDomainDataSource1.SubmitChanges();
	}

Zde vynutíme promítnutí změn na server. Toto je u internetu sporný postup z hlediska výkonu - tam může být lepší mít tlačítko, které to udělá pro celou skupinu najednou.

 

Nyní můžeme aplikaci spustit. Objeví se prázdný formulář, kliknutím v horní části můžeme přidat nový záznam.

VyrociFormular1

 

Vystavení aneb deployment

Otevřeme stránky českého poskytovatele hostingu ASPONE tj http://www.aspone.cz

Vybereme Webhosting, Freehosting, dáme objednat, vybereme název (vyroci.aspone.cz – samozřejmě musíte vybrat něco jiného, když už toto moje existuje), pokračujeme na souhlas s podmínkami, buď se zaregistujeme nebo přihlásíme a definitivně potvrdíme.

VyrociAspone2

Přijde email, v němž jsou přístupové údaje, k administraci a k FTP.

 

Než se dáme do vystavení ve VisualStudio, nastavíme v referencích webového projektu odesílání WCF.RIA knihoven na server, protože standardně na ASPONE nejsou.

 

Čili nastavíme CopyLocal na true pro:
System.ServiceModel.DomainServices.EntityFramework
System.ServiceModel.DomainServices.Hosting
System.ServiceModel.DomainServices.Server

 

Na webovém projektu dáme Publish, vybereme FTP, nastavíme kam ukládat a zadáme login a heslo. Samotné vystavení chvíli trvá, protože se kopíruje databáze, i knihovny Teleriku.

Přihlásíme se nějakým FTP klientem (například FAR) na onen server, vlezeme do složky www/App_Data a smažeme LDF soubor – systém ASPONE si jej při prvním přístupu vygeneruje sám, jinak by nám to nefungovalo.

 

Otevřeme web.config a změníme connection string, sekci mezi quot; následovně:

data source=.\sqlexpress;AttachDbFilename=|DataDirectory|\Vyroci.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True;Database=42754952487458754

To číslo na konci musí být unikátní, takže si jej změňte.

http://vyroci.aspone.cz/VyrociTestPage.html

Pokud se objeví formulář, ale při přístupu dojde k chybové hlášce „Not found“, tak běžte na web http://www.aspone.cz ,  přihlašte se a v kontaktním formuláři napište žádost o zřízení FullTrust práv pro vaší freehostingovou aplikaci, můžete dodat že se jedná o tutoriál XAML.CZ, ať zbytečně nepátrají po příčině problému. U placených hostingů, pokud už nějaký u ASPONE máte, by toto nemělo být problémem.

VyrociFormular4

U některého z dalších pokračování se budu těšit.

Pár poznámek, doplněných později (29.6.2011)

Uvedený postup má jednu chybu. Pokud máte v detailu položku, která není součástí řádku gridu (zde Popis) a změníte pouze tuto položku, pak není vyvolána událost RowEditEnded, respektive řádek se vůbec nepřepne do editačního režimu. Dá se to řešit ručním přepnutím za pomoci odchycení vstupu v položce, což by ale poněkud znepřehlednilo kód a tak to prostě už ponechám jak to bylo. Telerik to označuje za vlastnost s tím, že v detailu může být “cokoliv” a není v silách gridu odchytávat změny na “čemkoliv”. Budiž. 

Osobně grid-only editaci používám jen na opravdu malé číselníky ( z hlediska počtu “sloupců”, typicky ID+NAZEV ). Cokoliv jiného už si volá po použití RadDataForm .
RowDetail má naopak neocenitelné výhody při prohlížení, kdy je grid readonly a uživatel zobrazením detailu může vidět to, co se prostě do řádku nevejde.

Dále jsem přidal obsluhu promítnutí změn po smazání řádku (událost Deleted v Gridu).

A nakonec jsem provedl deploy s “komerčními” runtime knihovny, takže to již nepíše po spuštění “Trial” informaci jako původní verze (jen aby to někoho nepřekvapilo, funkčně jsou knihovny stejné, klidně zkoušejte na trial verzi).

Komentáře

ukládám komentář, vyčkejte prosím..
  1. Buďte první, kdo napíše komentář.

@xamlcz

  • RT @jvanrhyn: XAML, It's a bit like olives. Takes a while to get used to. But once you're used to it. It is actually pretty good. <3 XAML
  • RT @moser_christian: WPF Inspector 0.9.7 is released. It supports .NET 3.5 and 4.0 The project is now open source and available on CodeP ...
  • Jeff Handley oznámil vydání WCF RIA Services v.1.0 SP1 RTM http://bit.ly/gOgckn ke stažení na http://bit.ly/gVAXdK
  • jedna výzva pro Brno. Byl někdo z vás na přednášce o RIA v MS Akvárku? Dejte o sobě vědět. Děkuji
  • také jste uvažovali o tom, že zkusíte na projekt použít Caliburn Micro nebo naopak Prism 4? A co tak obojí, šlo by to nebo ne? Již brzy