Risipa de key_press | Programare

Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Risipa de key_press | Programare - Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Prima Aplicatie WPF

Initial am vrut sa scriu (e in lucru) cateva cuvinte care sa reprezinte o introducere in WPF, insa dupa ce am vazut ca merge destul de greu cu introducerea am decis sa sar deocamdata respectiva etapa si sa incep direct prezentarea tehnologiei, urmand ca undeva, in viitor, sa postez si acea parte introductiva, foarte importanta, insa mai greu de scris si documentat. Stiu… Ar fi trebuit sa incep prin a povesti ce este si la ce e bun WPF, cum functioneaza si de ce etc.

Despre ce voi scrie astazi: voi scrie o aplicatie WPF simpla, prin care voi explica modul de lucru cu WPF, partile componente ale unui proiect de acest tip, modul de scriere al codului, structura codului etc. Aplicatia de astazi este… “Friends List” – o aplicatie simpla, care imi va permite sa imi construiesc o lista de prieteni (lista de dusmani o sa fie in alta aplicatie). As vrea ca fereastra acestei aplicatii sa arate cam asa:

schita aplicatiei


Din ce e alcatuita aceasta fereastra? Din cateva controale simple: un texbox, un buton si o lista. Aplicatia functioneaza in felul urmator: un string (nume) este introdus in texbox si la apasarea butonului Add respectivul string este adaugat in lista de prieteni.

Sa incepem:

Deschid o fereastra de Visual Studio (in cazul meu 2010), New Project -> WPF Application. Numele pe care l-am ales eu pentru aceasta aplicatie este FriendsList

Tocmai am creat un proiect in care sa dezvolta aceasta prima aplicatie. Daca totul a decurs OK, ar trbui sa vedem in Visual Studio ceva de genul:

Daca fereastra Solution Explorer nu este vizibila ea poate fi activata din meniul View (apasand Solution Explorer). In Solution Explorer vedem ca Visual Studio a adaugat proiectului nostru cateva fisiere:

Nu voi explica in acest moment ce reprezinta fiecare componenta a solutiei, este suficient sa stim ca tot codul nostru pentru aceasta aplicatie va fi scris in MainWindow.xaml si in MainWindow.xaml.cs.
In acest moment fisierul MainWindow.xaml are urmatorul cod (XAML):

<Window x:Class="FriendsList.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        
    </Grid>
</Window>

Intuitiv pot sa spun ca nodul Window defineste fereastra aplicatiei, si are 3 parametri (atribute) pe care ii pot modifica imediat si vedea rezultatul acestei modificari: Title, Height si Width. Pentru inceput voi atribui acestor atribute urmatoarele valori: Title=”Friends List” Height=”250″ Width=”300″. Acum codul arata asa:

<Window x:Class="FriendsList.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Friends List" Height="250" Width="300">
    <Grid>
        
    </Grid>
</Window>

Voi apasa tasta F5 pentru a rula aplicatia:

Tocmai am creat si executat prima aplicatie WPF (e adevarat ca nu face nimic, deocamdata). Acum e timpul sa adaugam elementele pe care fereastra vreau sa le contina: textbox-ul, butonul si lista. Pare simplu? Nu e! Adica nu e la fel de simplu pe cat este in WinForms, unde cu cateva click-uri se poate construi o fereastra. In WPF, penru a adauga un control el trebuie adaugat unui alt control, care devine controlul parinte; exista, 2 tipuri de elemente parinte: elemente container (care gazduiesc mai multe elemente child) si elemente care pot avea un singur copil, care este definit ca si continut (Content). Elementul top al oricarei aplicatii WPF este fereastra insasi. Fereastra este un element de tipul celor care pot acea un singur element copil, Content. Pentru a putea adauga intr-o fereastra toate elementele de care avem nevoie, primul lucru pe care trebuie sa facem este sa ii adaugam ferestrei un element de tip container.

Sunt mai multe elemente de tip container (despre are voi scrie in detaliu in curand). Voi folosi acum StackPanel, un container care isi afiseaza elementele copil in ordinea in care apar, fie unul langa altul, fie unul deasupra celuilalt. Acum nu vreau sa intru in detalii despre cum functioneaza fiecare componenta, scopul este crearea unei aplicatii (oarecum functionale) si exemplificarea modului in care o aplicatie se contruieste. In articolele viitoare vor fi date explicatii detaliate despre controale, despre proprietatile acestora, despre felul cum ele functioneaza si se comporta.

In codul generat de Visual Studio, in fisierul MainWindow.xaml se poate vedea ca primul element al ferestrei este Grid; in acest moment nu voi folosi acest tip de container, ci ul altul StackPanel. Voi inlocui Grid cu StackPanel. Codul XAML arata acum asa:

<Window x:Class="FriendsList.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Friends List" Height="250" Width="300">
    <StackPanel>
        
    </StackPanel>
</Window>

StackPanel este un elemetn container, el poate avea mai multe elemente copil. Pentru a desena interfata aplicatie voi avea nevoie de 2 containere de tip StackPanel. Acestea vor fi copii ale primului StackPanel:

<Window x:Class="FriendsList.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Friends List" Height="250" Width="300">
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            
        </StackPanel>
        <StackPanel>

        </StackPanel>
    </StackPanel>
</Window>

A se ramarca atributul Orientation=”Horizontal” adaugat primului container. In mod prestabilit elementele adaugate unu StackPanel sunt adaugate unul peste altul. Stabilind valoarea atributului Orientation Horizontal ii spunem containerului sa deseneze elementele copil unul langa altul (orizontal). In momentul acesta avem 2 containere in care sa putem introduce elementele de care avem nevoie in aplicatie. In primul container voi introduce un textbox si un buton, iar in al doilea voi introduce un ListBox. Deasemeni voi stabili si cateva atribute pentru elementele introduse:

<Window x:Class="FriendsList.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Friends List" Height="250" Width="300">
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBox Width="120" Margin="5 0" />
            <Button Content="Add" Padding="9 0" Margin="5 0"></Button>
        </StackPanel>
        <StackPanel>
            <ListBox>
                <ListBoxItem Content="aa" />
                <ListBoxItem Content="bb" />
            </ListBox>
        </StackPanel>
    </StackPanel>
</Window>

Apas F5 pentru a rula aplicatia:


Plus, minus, fereastra arata asemanator cu ceea ce mi am propus cand am desenat schita ferestrei.

In primul StackPanel am urmatorul cod:

        <StackPanel Orientation="Horizontal">
            <TextBox Width="120" Margin="5 0" />
            <Button Content="Add" Padding="9 0" Margin="5 0"></Button>
        </StackPanel>

Se vede ca am adaugat doua elemente TextBox si Button pentru care am stabilit cateva proprietati. Pentru TextBox am stabilit width 250 si margini laterale de 5. Pentru buton am Padding (lateral) de 9, margini laterale de 5 si proprietatea Content este Add.
In al doilea StackPanel am numai lista (am adaugat si 2 elemente acestei liste pentru a vedea cum arata):

        <StackPanel>
            <ListBox>
                <ListBoxItem Content="aa" />
                <ListBoxItem Content="bb" />
            </ListBox>
        </StackPanel>

Tot ce mai trebuie sa fac e sa ma ocup de partea functionala, respectiv de evenimenul Click asociat butonului. Pentru asta voi modifica putin codul XAML care defineste butonul:

<Button Content="Add" Padding="9 0" Margin="5 0" Click="Button_Click"></Button>

Apas tasta F7 pentru a deschide fisierul cs asociat fisierului xaml. Aici voi avea (daca nu am scriu) codul care va intercepta evenimenul Click. In momentul asta fisierul MainWindow.xaml.cs trebuie sa arate asa:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FriendsList
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {

        }
    }
}

In momentu asta imi dau seama ca am uitat sa dau nume elementelor de care am nevoie acum. Am nevoie sa pot identifica TextBox-ul si Listbox-ul. Pentru asta voi completa la fiecare dintre aceste elemente cosul XAML cu atributul Name. TextBox-ul va primi: Name=”txtFriend” iar Listbox-ul: Name=”lstFriends”. In acest moment imi este foarte usor sa ajung la oricare dintre aceste elemente in fisierul cs.
Dupa aceste modificari codul XAML arata asa:

<Window x:Class="FriendsList.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Friends List" Height="250" Width="300">
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBox Width="120" Margin="5 0" Name="txtFriend" />
            <Button Content="Add" Padding="9 0" Margin="5 0" Click="Button_Click"></Button>
        </StackPanel>
        <StackPanel>
            <ListBox Name="lstFriends">
                <ListBoxItem Content="aa" />
                <ListBoxItem Content="bb" />
            </ListBox>
        </StackPanel>
    </StackPanel>
</Window>

Tot ce imi mai ramane de facut in acest moment este sa scriu codul pe care vreau sa il execut in momentul in care butonul este apasat (Click). Codul asociat evenimentului Click trebuie sa creeze un nou element in lista, element caruia sa ii atribue ca si Content textul continut in txtFriend:

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ListBoxItem li = new ListBoxItem();
            li.Content = txtFriend.Text;
            txtFriend.Clear();
            lstFriends.Items.Add(li);
            txtFriend.Focus();
        }

Dupa cum se poate vedea, in metoda care trateaza evenimentul Click creez (de data asta nu in XAML) un nou element pe care il adaog in lista. Pentru un plus de functionalitate am decis ca in momentul in care “prietenul” este adaugat in lista, numele lui (textul) este sters din TextBox, si in plus, Textbox-ul primeste si focus, pentru a nu fi nevoiti sa dam un click suplimentar in momentul in care vrem sa mai introducem un nume.

Cateva concluzii:

Pana in acest moment am construit o aplicatie simpla (de tip Hello World) folosind WPF. Limbajele folosite in acest proiect sunt XAML, cu o structura de tip XML, si c#. Logica aplicatiei este separata de prezentare in acest fel. Fiecare fisier XAML are asociat un fisier c#. Prin XAML sunt definite elementele grafice ale aplicatiei, iar c# se ocupa de partea de logica, de prelucrare a datelor. Dupa cum am vazul in momentul tratari evenimentului Click, ceea ce se poate realiza in XAML, respectiv crearea de elemente noi pentru UI, se poate face si in c# – crearea si adaugarea elemntelor listei.

Ce am vrut sa demonstrez pana acum, si sper sa fi reusit, este simplitatea cu care se poate construi ceva functional cu WPF. Oricine care are minime cunostinte de programare poate in scurt tip sa inteleaga si sa foloseasca aceasta tehnologie. Odata cu WPF (o sa vorbesc despre asta in viitor) primim “gratis” si Silverlight.

Ce urmeaza:

In continuare voi descrie componentele (controalele) standard care vin cu WPF si cum se folosesc acestea. Aceasta imi va lua cateva articole (5 cel putin). In articolul urmator voi vorbi despre controalele de tip container.

Category: Uncategorized
  • anamaria says:

    1)am de facut o aplicatie cv in genu cum e aia d mai sus numai k eu treb sa adaug si un buton de stergere,si sa functioneze atunci knd doresc sa sterg “aa” din lista d prieteni,am dat ex p ex tau.
    2)o alta tema ar fii sa adaug un video in wpf si sa fac ca acest video sa fie cat mai complicat folosind multe butoane si label-uri.ma puteti ajuta cu niste sfaturi,va rog.

    March 22, 2013 at 9:25 am
    • marius says:

      Solutia cea mai eleganta ar fi sa abordezi o arhitectura MVVM (Model-View-ViewModel) in care sa legi prin Binding butoanele de proprietati de tip ICommand, listele de proprietati de tip ObservableCollection, textele de proprietati de tip string, etc. Astfel, daca doresti stergerea unui element din lista, ajunge sa apesi pe butonul dorit, care este legat printr-un ICommand de rutina care sterge pur si simplu din colectia ObservableCollection.
      Pentru video ai clasa MediaElement, care poate fi foarte usor folosita din XAML.

      April 29, 2013 at 12:33 pm

Your email address will not be published. Required fields are marked *

*