WPF adresář - 1. díl
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

WPF adresář - 1. dílWPF adresář - 1. díl

 

WPF adresář - 1. díl

Google       Google       3. 2. 2008       23 924×

Ukážeme si, jak je pomocí XAMLu snadné udělat vzhledově pěknou aplikaci a pomocí C# ji oživit. Cílem tohoto seriálu bude vytvoření adresáře pro správu kontaktů.

Vítejte u prvního dílu seriálu o tvorbě jednoduchého adresáře na údržbu kontaktů pomocí XAMLu a C#.

V době psaní článku toho o XAMLu a WPF celkově tady na Programujte moc není , ale je to obrovská škoda, protože XAML je skutečně mocný jazyk díky svým schopnostem pro práci s grafikou a svojí jednoduchostí. Ty, kteří nevědí, o co jde, odkážu na jednu z výjimek.

Jako vždy budu používat Visual Studio 2008 ve verzi Professional. Pokud máte jakoukoliv jinou 2008, tak to nevadí, nepotřebujete nic jiného kromě .NET Frameworku 3.5. Pro VS 2005 je nutné stáhnout některé věci navíc, ale tím už nebudu zdržovat. Předem vás také upozorním, že cílem tohoto seriálu není vytvoření kompletně funkčního adresáře, ale poukázání na některé zajímavé schopnosti a možnosti využití XAMLu. S největší pravděpodobností se nebudu s většinou C# logiky vůbec zabývat (dialogy pro export kontaktů, shromažďování kontaktů do skupin, atd.)

Začínáme

Po zapnutí Visual Studia vytvoříme nový WPF Application projekt. Já si ho pojmenoval Adresar. Vznikla nám základní XAML struktura, ale nikde není žádný .cs soubor, který potřebujeme pro funkčnost programu. Přidáme si kontakty.cs tak, že klikneme pravým tlačítkem na projekt Adresar v Solution Exploreru a dáme Add → Class.

Následující kód přepište/zkopírujte do kontakty.cs, vzápětí si ho trošku přiblížíme.

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Data;
using System.Collections.ObjectModel;

namespace Adresar
{
    public class Kontakt
    {
        private Uri homePage;

        //Nastavení křestního jména - vlastnost
        public String JmenoKrestni
        {
            get; set;
        }

        //Nastavení příjmení - vlastnost
        public String JmenoPrijmeni
        {
            get; set;
        }

        //Nastavení e-mailové adresy - vlastnost
        public String Email
        {
            get; set;
        }

        //Webová adresa - vlastnost
        public Uri HomePage
        {
            get { return homePage; }
            set { homePage = value as Uri; } 
        }

        //Místo bydliště - vlastnost
        public string AdresaDomu
        {
            get; set;
        }

        //Adresa do zaměstnání - vlastnost
        public string AdresaZamestnani
        {
            get; set;
        }
		

    }


    //Pomocí této kolekce budeme vůbec s kontakty moct něco dělat
    public class SeznamKontaktu : ObservableCollection<Kontakt>
    {
        public SeznamKontaktu()
            : base()
        {
        }

    }
}

Kód byl na základě připomínky jednoho ze čtenářů (děkuji Martinu Jonášovi) vylepšen o jednu z vymožeností .NET Frameworku 3.5 – Automatic Properties. Díky tomu můžeme nahradit „běžné“ get/set bloky (return x; a x=value;) kratším get;set; a kompilátor si vše potřebné už doplní sám.

Další vlastnosti si samozřejmě přidejte dle libosti, jako časté mě teď napadá třeba telefonní číslo nebo čísla/adresy různých messengerů. Proměnné začínají malým písmenem, vlastnosti, které k nim patří jsem pojmenoval stejně jako jejich proměnné s tím rozdílem, že mají první písmeno v názvu velké. Jak si můžete všimnout, třída SeznamKontaktu je odvozená od ObservableCollection<T>, ze syntaxe je patrné, že je to generická třída. Tato třída je ve WPF novinka, implementuje některé zajímavé metody, které se týkají hlavně změn kolekce (např. OnCollectionChanged – vyvolá se, pokud je nějak změněn některý prvek. Všechny metody by vydaly na celý článek, takže zájemce odkážu na MSDN.

To jsme trošku odbočili, takže zpátky k tématu. Vytvoříme si další soubor kontakty, tentokrát ve formátu .txt (v Add New Item pod názvem Text File), který bude uchovávat všechny naše kontakty společně s jejich informacemi. Pro ilustraci použiji následující obsah:

Honza;Novák;honza@seznam.cz;http://honzikuvblog.cz;Pražská 324, Praha; Skalecká 61, Praha
Ondra;Brokl;ondra@gmail.com;http://ondruvblog.com;5. května 27, Liberec; Pracuje doma

Skládá se ze dvou řádků informací o dvou lidech ve formátu
jméno;příjmení;e-mail;URL;AdresaDomova;AdresaZaměstnání.

Teď si v Solution Exploreru označíme kontakty.txt a v okně Properties → Build Action nastavíme na Content. To určí, že náš soubor bude nedílnou součástí sestaveného programu. Druhou věcí, kterou nastavíme, je Copy to Output Directory na „Copy if newer“. Díky této úpravě se nám do výstupního adresáře zkopíruje nejnovější verze, kdybychom nechali „Do not copy“, soubor by se nám nezkopíroval vůbec a program by pak neměl z čeho načítat informace.

Abychom měli lepší kontrolu nad tím, co se bude dít po spuštění a ukončení aplikace, nastavíme handlery pro události StartProgramu a KonecProgramu. Tento kód zkopírujte do App.xaml.cs, dovnitř třídy App.

public App()   
{   
    //potlačí výchozí konstruktor   
}   

void StartProgramu(object sender, StartupEventArgs args)   
{   
    //Co se stane při spuštění aplikace?   
    Window1 hlavniOkno = new Window1(); //vytvoří se instance okna   
    hlavniOkno.WindowStartupLocation = WindowStartupLocation.CenterScreen; //okno se vycentruje   

    hlavniOkno.Show(); //okno se objeví   
}   

private void KonecProgramu(Object sender, ExitEventArgs e)   
{   
} 

Vše, co je nahoře, byste mohli znát, ale teď přijde na řadu, pro některé možná neznámý, XAML. Tímto kódem přepíšeme obsah souboru App.xaml.

<Application xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
x:Class="Adresar.App"	         
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	Startup="StartProgramu"
	Exit="KonecProgramu">
</Application>

Protože máme třídu App deklarovanou jako partial, využijeme parametru Class, který se zadává ve tvaru namespace.třída. Díky této akci budou .xaml a .cs soubory provázány a my odtud můžeme zavolat metody StartProgramu a KonecProgramu.

To vše je sice moc pěkné, ale pořád nevidíme žádný výsledek. Náplní dnešního dílu bude vytvoření grafického rozhraní. Bude se skládat z Gridu který bude přes celé okno aplikace a bude v sobě obsahovat ještě DockPanel pro každý z následujících prvků: menu, toolbar, status lišta a levé okno, ve kterém bude seznam našich kontaktů. Zbytek bude pracovní plocha, kde se budou objevovat informace o zvoleném kontaktu. Pro představu o rozložení jsem udělal tenhle obrázek:

Teď si otevřeme Window1.xaml, který zastupuje okno, které se vytvoří při spuštění programu. Jeho kód by mohl vypadat nějak takhle:

<Application xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
x:Class="Adresar.App"	         
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	Startup="StartProgramu"
	Exit="KonecProgramu">
</Application>
<Window 
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	x:Class="Adresar.Window1"
	Name="Adresar" 
	Title="Adresář - programujte.com" 
	Loaded="NacteneOkno" 
	SizeToContent="WidthAndHeight">

    <Grid Background="#FFFFFFFF" Name="Zaklad" Width="640" Height="480">


    </Grid>
</Window>

Program nám teď nepůjde chvíli zkompilovat, protože pomocí x:Class odkazujeme na třídu Window1, která má obsahovat event NacteneOkno, ale zatím neobsahuje.

Nikde nemáme přesně nastavenou velikost okna, ale to nevadí, díky SizeToContent nastavenému na WidthAndHeight si okno vezme šířku a výšku z největšího prvku v oknu (v našem případě je to Grid, stejně jako v naprosté většině dalších případů). Vlastnost Background jsme nastavili na bílou (#FFFFFFFF), jméno na Zaklad (jména nemusíme prvkům dávat, pokud na ně nebudeme odkazovat, ale vážně doporučuji to dělat, ať už kvůli přehlednosti, nebo dobrému zvyku) a nakonec rozměry na 640×480, které zároveň určí velikost celého okna.

Grid je vlastně taková tabulka, do které se jednotlivé prvky umisťují pomocí řádků a sloupců, hned si to ukážeme přidáním horního menu pomocí DockPanel (ten možná znáte z WinForms, elementy v něm se přilepí k jedné ze stran okna).

Naše menu bude obsahovat dvě hlavní záložky (Soubor a Upravit) a několik jejich potomků.

<!-- Menu-->
                <!--definice DockPanelu pro menu-->
        <DockPanel Name="DockPanel_Menu" 
         Grid.Column="0" 
         Grid.ColumnSpan="1" 
         Grid.Row="0" 
         Grid.RowSpan="1" 
         Margin="1,0,0,0" 
         HorizontalAlignment="Stretch" 
         VerticalAlignment="Top" 
         Width="Auto" Height="28">
                <!--/definice DockPanelu pro menu-->
            <!--vzhled Menu-->
            <Menu Grid.Column="0" Grid.ColumnSpan="1" 
        Grid.Row="0" Grid.RowSpan="1" 
        HorizontalAlignment="Stretch" VerticalAlignment="Top"  
        Height="25" Background="White">
                <!--první záložka - Soubor + podskupiny-->
                <MenuItem Header="Soubor">
                    <MenuItem Header="Nový kontakt" Click="SpustitPruvodcePridani"/>
                    <MenuItem Header="Nová skupina" Click="NeniImplementovano"/>
                    <Separator />
                    <MenuItem Header="Vlastnosti" Click="NeniImplementovano"/>
                    <MenuItem Header="Smazat" Click="NeniImplementovano"/>
                    <MenuItem Header="Importovat">
                        <MenuItem Header="Adresář..." 
                  Click="NeniImplementovano"/>
                        <MenuItem Header="Vizitky..." 
                  Click="NeniImplementovano"/>
                    </MenuItem>
                    <Separator />
                        <!--tlačítko Konec včetně nápovědy-->
                    <MenuItem Header="Konec" InputGestureText="Alt-F4" Click="Konec">
                        <MenuItem.ToolTip>
                            <ToolTip>
                                Klikněte pro ukončení aplikace
                            </ToolTip>
                        </MenuItem.ToolTip>
                    </MenuItem>
                </MenuItem>
                <!--tady končí první záložka Soubor-->
            </Menu>
            <!--záložka Upravit...-->
            <Menu Grid.Column="1" Grid.ColumnSpan="1" 
        Grid.Row="0" Grid.RowSpan="1" 
        HorizontalAlignment="Left" VerticalAlignment="Top" 
        Width="80" Height="25" Background="White">
                <MenuItem Header="Upravit">
                    <MenuItem Command="ApplicationCommands.Copy"/>
                    <MenuItem Command="ApplicationCommands.Paste"/>
                </MenuItem>

            </Menu>
            <!--...až sem-->
        </DockPanel>

Řekl bych, že není nutné kód nějak zvlášť popisovat, klíčová slova jsou dobře srozumitelná a měněním hodnot si můžete vyzkoušet jak přesně fungují. Snad jen, že řádky (rows) a sloupce (columns) se počítají od nuly. Máme-li okno rozdělené na čtyři malá pomocí Grid, pravý dolní roh bude <Grid.Row=“1“ Grid.Column=“1“/>.

Další na řadě je toolbar, neboli taková lišta plná ikonek pro rychlé akce. Protože primární funkce našeho programu bude přidávání a odebírání kontaktů, tak na tyto metody (napíšeme je později) přidáme do toolbaru odkazy.

<!-- ToolBar -->
        <DockPanel Name="DockPanel_Toolbar" 
			Grid.Column="0" Grid.ColumnSpan="1" 
			Grid.Row="0" Grid.RowSpan="1" 
			Margin="1,25,0,0" 
			HorizontalAlignment="Stretch" VerticalAlignment="Top" 
			Width="Auto" Height="26">
            <ToolBar DockPanel.Dock="Top"
					 HorizontalAlignment="Stretch" 
				     VerticalAlignment="Center">
                <Button Click="SpustitPruvodcePridani" 
                                ToolTip="Přidat kontakt"
                                Content="+" />
                   
                <Button Click="NeniImplementovano" 
                                ToolTip="Smazat kontakt"
                                Content="-" />
            </ToolBar>

        </DockPanel>

Rychlé a jednoduché, že? ToolBar je nastavený, aby se přilepil nahoru, ale tam už je menu, takže automaticky budeme mít menu a toolbar pod sebou. Margin (v XAMLu se udává v pořadí: zleva, shora, zprava, zdola) seshora je nastavený na 25, kvůli výšce menu.

Dnes už uděláme jenom tři věci, jedna z nich je přidání levého panelu, ve kterém se budou vypisovat všechny uložené kontakty. Asi nejvhodnější je použití ListBoxu, zatím si jenom připravíme pole, v dalším díle přidáme metodu pro vypisování.

<!--levý panel-->
        <DockPanel Name="DockPanel_LevyPanel" 
			Grid.Column="0" Grid.ColumnSpan="1" 
			Grid.Row="0" Grid.RowSpan="1" 
			Margin="1,54,0,0" 
			HorizontalAlignment="Left" 
                  VerticalAlignment="Stretch" 
			Width="200" Height="Auto" >

            <ListBox Name="vsechnyKontakty" 
				SelectionChanged="JeZvolenyKontakt">
                <ListBox.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="Přidat kontakt" 
	   					      Click="SpustitPruvodcePridani"/>
                        <MenuItem Header="Přidat skupinu" 
							Click="NeniImplementovano"/>
                    </ContextMenu>
                </ListBox.ContextMenu>
            </ListBox>

        </DockPanel>

Jediné, co tady stojí za zmínku, je ListBox.ContextMenu – dopředu jsme si připravili kontextovou nabídku, která se objeví po kliknutí na kontakt pravým tlačítkem myši. Kromě toho neumí náš ListBox vůbec nic.

Předposlední věc je status lišta – StatusBar. Zobrazování textu v ní docílíme tak, že do StatusBar prvku přidáme TextBlock.

<DockPanel Name="DockPanel_StatusLista" 
			Grid.Column="0" Grid.ColumnSpan="1" 
			Grid.Row="1" Grid.RowSpan="1" 
			Margin="1,31,0,0" 
			HorizontalAlignment="Stretch" VerticalAlignment="Bottom" 
			Width="Auto" Height="25">

            <StatusBar BorderBrush="Black" 
				BorderThickness="1" DockPanel.Dock="Left">

                <TextBlock Name="tb" 
					Foreground="Black">Status lišta
				</TextBlock>

            </StatusBar>

        </DockPanel>

Na závěr uděláme něco se zbytkem okna. Ten bude v budoucnu zobrazovat podrobné informace o zvoleném kontaktu, zatím si jenom připravíme rámeček.

<!--Hlavní okno-->
        <Frame Name="Frame_Zbytek" 
			Grid.Column="0" Grid.ColumnSpan="1" 
			Grid.Row="0" Grid.RowSpan="1" 
			Margin="201,65,0,0" 
			HorizontalAlignment="Stretch" 
			VerticalAlignment="Stretch" 
			Height="Auto"/>

To je pro dnešek vše, udělali jsme si nefunkční program, naučili jsme se základy XAMLu a v příštím dílu už zprovozníme přidávání kontaktů. Doufám, že pro vás byl XAML kód pochopitelný, někdy snad budu věnovat článek základům. V případě jakýchkoliv nejasností pište do diskuze.

Na závěr přikládám ukázku toho, co jsme až doteď vytvořili (zájemci nechť si přidají prázdné metody NeniImplementovano(), SpustitPruvodcePridani(), NacteneOkno(), Konec() a JeZvolenyKontakt() do Window1.xaml.cs).

Zdroj: http://windowsclient.net/downloads/folders/hands-on-labs/entry3719.aspx

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
Jakub studuje informatiku na FIT ČVUT, jeho oblíbenou platformou je .NET.
Web     Twitter     Facebook     LinkedIn    

Nové články

Obrázek ke článku Hybridní inteligentní systémy 2

Hybridní inteligentní systémy 2

V technické praxi využíváme často kombinaci různých disciplín umělé inteligence a klasických výpočtů. Takovým systémům říkáme hybridní systémy. V tomto článku se zmíním o určitém typu hybridního systému, který je užitečný ve velmi složitých výrobních procesech.

Obrázek ke článku Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Vedení týmu v oboru informačních technologií se nijak zvlášť neliší od jiných oborů. Přesto však IT manažeři čelí výzvě v podobě velmi rychlého rozvoje a tím i rostoucími nároky na své lidi. Udržet pozornost, motivaci a efektivitu týmu vyžaduje opravdu pevné manažerské základy a zároveň otevřenost a flexibilitu pro stále nové výzvy.

Obrázek ke článku Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Za poslední rok se podoba práce zaměstnanců změnila k nepoznání. Především plošné zavedení home office, které mělo být zpočátku jen dočasným opatřením, je pro mnohé už více než rok každodenní realitou. Co ale dělat, když se při práci z domova ztrácí motivace, zaměstnanci přestávají komunikovat a dříve fungující tým se rozpadá na skupinu solitérů? Odborníci na personalistiku dali dohromady několik rad, jak udržet tým v chodu, i když pracovní podmínky nejsou ideální.

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý