• Nu S-Au Găsit Rezultate

WPF – Windows Presentation Foundation

N/A
N/A
Protected

Academic year: 2022

Share "WPF – Windows Presentation Foundation "

Copied!
133
0
0

Text complet

(1)

Windows Presentation Foundation – WPF

Cuprins

Windows Presentation Foundation – WPF ... 1

Cuprins ... 1

Bibliografie: ... 3

Introducere in modelul de programare XAML ... 4

Ordinea de procesare a proprietatii si evenimentului ... 5

Spatii de nume ... 5

Elemente proprietate ... 6

Converteri de tip ... 10

Extensii pentru marcare - Markup Extensions ... 11

Descendenti ai elementelor object ... 13

Proprietatea Content ... 14

Colectie de articole ... 14

Valoare ce poate fi convertita la elementul obiect ... 16

Spatii de nume proprii – declaratie ... 16

WPF – Fundamente ... 19

Arbori logici si arbori vizuali ... 19

Proprietati dependente. Proprietati atasate. ... 21

Proprietati dependente ... 22

Clasa DependencyProperty ... 22

Exemplu complet cu proprietate dependenta ... 31

Proprietati atasate ... 36

Proprietati atasate in cod ... 37

Metadata proprietatii atasate ... 38

Crearea unei proprietati atasate ... 38

Atributele proprietatii atasate ... 39

Construirea unei aplicatii WPF ... 42

Controlul marimii controalelor ... 42

Controlarea pozitiei ... 44

Aliniere continut ... 45

FlowDirection ... 46

Layout WPF ... 47

Structura unei aplicatii Window standard ... 55

Clasa Window ... 55

Clasa Application ... 56

(2)

Controale ... 58

Controale ce contin un singur articol ... 59

Controale ce contin o colectie de articole ... 60

Clasa EventManager ... 64

Handler-i ai clasei si handler-i ai instantei ... 66

Handler-i virtuali ... 67

Strategii de rutare si metode pentru evenimente ... 67

Evenimente in XAML si cod ... 68

Evenimente atasate ... 71

Evenimente de la tastatura ... 72

Comenzi ... 73

ComboBox ... 80

ComboBoxItem ... 81

ListBox ... 81

ListView ... 82

DataGrid ... 83

Coloane auto generate ... 84

Selectare randuri si/sau celule ... 85

Meniuri ... 88

ContextMenu ... 89

TreeView ... 89

TreeViewItem ... 89

Accesare resurse binare ... 91

Accesare resurse din cod ... 91

Resurse Statice versus Resurse Dinamice ... 92

Resurse fara partajare ... 93

Data Binding ... 94

Concepte de baza in asocierea de date - Data Binding ... 94

Proprietatea Mode din Binding ... Error! Bookmark not defined. Actualizarea sursei - UpdateSourceTrigger ... 96

Creare binding ... 97

DataTemplate ... 113

(3)

Bibliografie:

Adam Nathan – WPF 4 Unleashed

MSDN

(4)

WPF – Windows Presentation Foundation

Windows Presentation Foundation (WPF) este compus din o multime de assembly pentru a crea aplicatii GUI.

Un principal avantaj al acestui model este separarea completa dintre designeri si dezvoltatori.

Designerii folosesc un limbaj numit eXtensible Application Markup Language - (XAML).

Spatiul de nume principal este System.Windows. Observatie

Spatiul de nume System.Windows.Forms este folosit pentru dezvoltarea aplicatiilor Windows clasice.

Introducere in modelul de programare XAML

Specificatia XAML defineste reguli ce mapeaza spatiile de nume din .NET, tipuri, proprietati si evenimente in spatii de nume XML, elemente si atribute.

XAML este bazat pe XML. Exista o mapare a tipurilor din CLR la tag-urile din XML, de la atributele din XML la proprietatile si evenimentele din CLR.

// XAML:

<MyObject SomeProperty='1' />

Observatie

MyObject este element in descrierea XML.

SomeProperty este atribut in descrierea XML de mai sus.

// C#

MyObject obj = new MyObject();

obj.SomeProperty = 1;

Observatie

MyObject este un tip in .NET.

SomeProperty este o proprietate in sensul C# .NET.

// XAML:

<Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

Content=”OK”/>

// C#:

System.Windows.Controls.Button b = new System.Windows.Controls.Button();

b.Content = "OK";

Tag-urile XML sunt definite in contextul unui namespace si acel namespace determina ce tag- uri sunt valide. In XAML se mapaeza namespaces-uri XML la colectii de assemblies si namespaces-uri CLR.

Declararea unui element XML in XAML – cunoscut ca element obiect (object element) – este echivalent cu a instantia obiectul corespunzator din .NET folosind constructorul implicit.

(5)

Setarea unui atribut (in XML) pe un element obiect este echivalent cu setarea proprietatii cu acelasi nume sau atribuirea unui handler pentru un eveniment cu acelasi nume (event

attribute).

Exemplu. Un buton are setata proprietatea Content si ataseaza o metoda (event handler) pentru evenimentul Click:

// XAML:

<Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

Content=”OK” Click=”button_Click”/>

// C#:

System.Windows.Controls.Button b = new System.Windows.Controls.Button();

b.Click += new System.Windows.RoutedEventHandler(button_Click);

b.Content = "OK";

Ordinea de procesare a proprietatii si evenimentului

La runtime, handler-ii pentru evenimente sunt atasati inaintea oricarei proprietati pentru orice obiect declarat in XAML – exceptie proprietatea Name care este setata imediat dupa

constructia obiectului. Acest lucru face posibila tratarea unui eveniment ca raspuns la setarea unei proprietati, si ca o consecinta a acestui fapt rezulta ca nu are importanta ordinea

atributelor folosite in XAML.

Spatii de nume

Elementul obiect radacina dintr-un fisier XAML trebuie sa specifice cel putin un spatiu de nume XML, spatiu de nume ce este folosit de elementul radacina precum si de toate elementele descendente.

Se pot declara spatii de nume XML aditionale, dar fiecare trebuie sa aiba un prefix distinct, prefix ce va fi utilizat pentru a identifica elemente din acel spatiu de nume.

De exemplu, WPF XAML foloseste un al doilea spatiu de nume cu prefixul x astfel : xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml/presentation Urmatoarele spatii de nume din .NET sunt mapate la

http://schemas.microsoft.com/winfx/2006/xaml/presentation

. System.Windows

. System.Windows.Automation . System.Windows.Controls

. System.Windows.Controls.Primitives . System.Windows.Data

. System.Windows.Documents

. System.Windows.Forms.Integration . System.Windows.Ink

. System.Windows.Input . System.Windows.Media

. System.Windows.Media.Animation . System.Windows.Media.Effects . System.Windows.Media.Imaging

(6)

. System.Windows.Media.Media3D

. System.Windows.Media.TextFormatting . System.Windows.Navigation

. System.Windows.Shapes . System.Windows.Shell

In majoritatea documentatiilor spatiul de nume WPF XML :

http://schemas.microsoft.com/winfx/2006/xaml/presentation este declarat ca spatiu primar in timp ce spatiul de nume al limbajului XAML

http://schemas.microsoft.com/winfx/2006/xaml este declarat ca spatiu secundar, prefixat cu x.

In XML se foloseste atributul xmlns pentru a defini noi namespace-uri.

// XAML :

<MyObject xmlns='clr-namespace:Samples' SomeProperty='1' />

// C#

using Samples;

MyObject obj = new MyObject();

obj.SomeProperty = 1;

In XAML, putem specifica locatia unui assembly pentru fiecare namespace:

// XAML:

<MyObject

xmlns='clr-namespace:Samples;assembly=samples.dll' SomeProperty='1' />

// C#

csc /r:samples.dll test.cs // compilator apelat din linia de // comanda

In mediul visual se adauga referinta la samples.dll urmat de folosirea lui using.

using Samples;

MyObject obj = new MyObject();

obj.SomeProperty = 1;

Elemente proprietate

XML este impartit in doua spatii: elemente si atribute. In termeni de obiecte, proprietati si evenimente, modelul XAML este mai apropiat de CLR. Exemplul de mai sus poate fi rescris astfel folosind un element descendent :

<MyObject

xmlns='clr-namespace:Samples;assembly=samples.dll'>

<MyObject.SomeProperty>

1

</MyObject.SomeProperty>

</MyObject>

(7)

Fiecare element proprietate este calificat cu tipul ce defineste acea proprietate. In exemplul de mai sus tipul este MyObject, iar proprietatea este SomeProperty.

Exemplu

Presupunem ca exista o proprietate Owner (MyObject are aceasta proprietate) pentru obiectul Persoana. Obiectul Persoana are proprietatile FirstName si LastName. Codul poate arata astfel folosind sintaxa XAML:

<MyObject

xmlns='clr-namespace:Samples;assembly=samples.dll'>

<MyObject.Owner>

<Persoana FirstName="Chris" LastName="Anderson" />

</MyObject.Owner>

</MyObject>

echivalent in C# cu:

MyObject mo = new MyObject();

Persoana persoana = new Persoana();

persoana.FirstName = "Chris";

persoana.LastName = "Anderson";

mo.Owner = persoana;

In exemplul de mai sus daca adnotam proprietatea Owner a obiectului MyObject cu atributul System.Windows.Markup.ContentPropertyAttribute atunci putem scrie;

<MyObject

xmlns='clr-namespace:Samples;assembly=samples.dll'>

<Person FirstName='Megan' LastName='Anderson' />

</MyObject>

Exemplu complet. Tipul MyObject trebuie definit astfel:

using System;

using System.Windows;

using System.Windows.Markup;

namespace ContentPropertySamples {

[ContentProperty("Owner")]

public class MyObject:UIElement {

public MyObject() { } private Persoana _owner;

public Persoana Owner {

get { return _owner; } set { _owner = value; } } } }

Tipul Persoana este definit astfel:

using System;

using System.Windows;

using System.Windows.Markup;

(8)

namespace ContentPropertySamples {

public class Persoana:UIElement {

public string FirstName { get; set; } public string LastName { get; set; } }

}

iar in XAML

<Window x:Class="ContentPropertySamples.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:lc='clr-namespace:ContentPropertySamples' Title="MainWindow" Height="350" Width="525">

<Grid>

<StackPanel>

<lc:MyObject x:Name="mo">

<lc:MyObject.Owner>

<lc:Persoana x:Name="persoana" FirstName='Megan' LastName='Anderson' />

</lc:MyObject.Owner>

</lc:MyObject>

<Label Name="label1" Content="Label clic"

PreviewMouseDown="label1_PreviewMouseDown">

</Label>

</StackPanel>

</Grid>

</Window>

si in code behind tratare eveniment PreviewMouseDown (am omis spatiile de nume):

namespace ContentPropertySamples {

public partial class MainWindow : Window {

public MainWindow() {

InitializeComponent();

}

private void label1_PreviewMouseDown(object sender, MouseButtonEventArgs e) {

MessageBox.Show(mo.Owner.FirstName + " " + mo.Owner.LastName, “Exemplu”);

} } }

(9)

La clic pe label

se va afisa:

Exemplu In C#:

System.Windows.Controls.Button b = new System.Windows.Controls.Button();

System.Windows.Shapes.Rectangle r = new System.Windows.Shapes.Rectangle();

r.Width = 40;

r.Height = 40;

r.Fill = System.Windows.Media.Brushes.Black;

b.Content = r; // Continutul butonului este un patrat

In XAML acest lucru poate fi scris astfel:

<Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”>

<Button.Content>

<Rectangle Height=”40” Width=”40” Fill=”Black”/>

</Button.Content>

</Button>

S-a folosit proprietatea Content pentru Button.

Se foloseste un element XML in locul unui atribut.

Folosind un atribut XML (Content este pe post de atribut, la fel Background) putem scrie :

<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

Content="OK" Background="White"/>

sau cu element proprietate :

<Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”>

<Button.Content> <!-- sintaxa cu element proprietate -->

OK

</Button.Content>

<Button.Background>

(10)

White

</Button.Background>

</Button>

Continutul unui control poate fi orice si-l putem stabili in momentul instantierii controlului.

Converteri de tip

Pentru exemplul anterior varianta C# este :

System.Windows.Controls.Button b = new System.Windows.Controls.Button();

b.Content = "OK";

b.Background = System.Windows.Media.Brushes.White;

Observam proprietatea White in C# si stringul "White" in XAML.

Un “converter” face conversia unui tip la alt tip (dupa cum sugereaza si numele).

Fara un "converter" pentru Brush, ar fi trebuit sa folosim sintaxa pentru elementul proprietate astfel :

<Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

Content=”OK”>

<Button.Background>

// aici e un converter pentru "White"

<SolidColorBrush Color=”White”/>

</Button.Background>

</Button>

Daca nu exista un converter in acest caz, am putea scrie:

<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

Content="OK">

<Button.Background>

<SolidColorBrush>

<SolidColorBrush.Color>

<Color A="255" R="255" G="255" B="255"/>

</SolidColorBrush.Color>

</SolidColorBrush>

</Button.Background>

</Button>

Si aici avem de a face cu un converter. "255" va fi convertit intr-un byte.

Observatie

Pentru ca un tip sau o proprietate sa accepte un converter, acesta/aceasta trebuie adnotata cu atributul TypeConverter.

[TypeConverter(typeof(BrushConverter)), …]

public abstract class Brush : … { … }

sau

(11)

[TypeConverter(typeof(FontSizeConverter)), …]

public double FontSize {

get { … } set { … } }

Extensii pentru marcare - Markup Extensions

Extensiile markup in XAML – incluse intre { } - constituie o modalitate de a extinde parser-ul markup pentru a produce markup-uri mai simple. Extensiile markup sunt implementate ca tipuri CLR si lucreaza asemanator ca definitiile atributelor CLR.

Oricand valoarea unui atribut este inclusa intre {}, XAML trateaza acest lucru ca o extensie si nu ca o expresie.

<Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

Background=”{x:Null}”

Height=”{x:Static SystemParameters.IconHeight}”

Content=”{Binding Path=Height, RelativeSource={RelativeSource Self}}”

/>

Ce e cu rosu reperzinta extensii, in rest parametri cu nume si valori.

Primul identificator dupa { este numele clasei extensie, clasa ce trebuie sa fie derivata din clasa MarkupExtension. Prin conventie numele acestor clase se termina cu Extension, dar care poate fi omis in XAML.

Clase :

NullExtension = Null ; StaticExtension = Static, etc.

Spatiul de nume pentru clasele exetensie ale limbajului de marcare este System.Windows.Markup, deci prefixul x trebuie utilizat pentru a-l localiza.

Parametrii pozitionali (SystemParameters.IconHeight de ex.) sunt tratati ca argumente string pentru constructorul clasei extensie.

Parametrii cu nume (Path, RelativeSource) permit setarea unor proprietati pe obiectul extensie construit. Valorile acestor proprietati pot fi valori date cu limbajul de marcare extins – se folosesc din nou {} sau valori literale.

StaticExtension permite folosirea proprietatilor statice, campurilor, constantelor si

enumerarilor in locul literalilor hard-coded. In acest caz, proprietatea Height a butonului este setata la inaltimea curenta a icoanelor din sistemul de operare, expusa de prorpietatea statica IconHeight din clasa System.Windows.SystemParameters.

Observatie

“{}{text}” are ca efect tratarea { si } drept caractere normale care nu fac parte din sintaxa.

(12)

Din cauza ca extensiile markup sunt clase cu conctructori impliciti, acestea pot fi utilizate cu sintaxa elementului proprietate.

Urmatorul cod este identic cu cel anterior:

<Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”>

<Button.Background>

<x:Null/>

</Button.Background>

<Button.Height>

<x:Static Member=”SystemParameters.IconHeight”/>

</Button.Height>

<Button.Content>

<Binding Path=”Height”>

<Binding.RelativeSource>

<RelativeSource Mode=”Self”/>

</Binding.RelativeSource>

</Binding>

</Button.Content>

</Button>

Exemple

<Canvas Name="Parent0">

<Border Name="Parent1"

Width="{Binding RelativeSource={RelativeSource Self}, Path=Parent.ActualWidth}"

Height="{Binding RelativeSource={RelativeSource Self}, Path=Parent.ActualHeight}">

<Canvas Name="Parent2">

<Border Name="Parent3"

Width="{Binding RelativeSource={RelativeSource Self}, Path=Parent.ActualWidth}"

Height="{Binding RelativeSource={RelativeSource Self}, Path=Parent.ActualHeight}">

<Canvas Name="Parent4">

<TextBlock FontSize="16"

Margin="5" Text="Display the name of the ancestor"/>

<TextBlock FontSize="16"

Margin="50"

Text="{Binding RelativeSource={RelativeSource FindAncestor,

AncestorType={x:Type Border}, AncestorLevel=2},Path=Name}"

Width="200"/>

</Canvas>

</Border>

</Canvas>

</Border>

</Canvas>

Rezultatul este:

(13)

Urmatoarele doua exemple sunt echivalente.

<Rectangle Fill="Red" Name="rectangle"

Height="100" Stroke="Black"

Canvas.Top="100" Canvas.Left="100"

Width="{Binding ElementName=rectangle, Path=Height}"/>

sau

<Rectangle Fill="Red" Height="100"

Stroke="Black"

Width="{Binding RelativeSource={RelativeSource Self}, Path=Height}"/>

Rezultatul este

Descendenti ai elementelor object

Un fisier XAML la fel ca fisierele XML trebuie sa aiba un singur element radacina.

Elementele obiect pot suporta elemente obiect descendente (elementele proprietate nu sunt elemente descendente).

Un element obiect poate avea urmatoarele tipuri de descendenti:

 valoare pentru o proprietate continut ;

 colectie de articole ;

 valoare ce poate fi convertita la elementul obiect.

In continuare le discutam pe fiecare in parte.

(14)

Proprietatea Content

Multe clase din WPF au o proprietate ce pastreaza continutul elementului. De exemplu

continutul unui Button poate fi text si/sau imagine si/sau dreptunghi, etc. Aceasta proprietate se numeste Content pentru Button si poate fi setata in XAML sau in cod.

Pentru alte controale proprietatea are alt nume, dar intra in categoria celor ce furnizeaza continutul controlului. Clasele ComboBox, ListBox, TabControl au proprietatea Items pentru a furniza continutul.

Exemplu: Buton ce contine un TextBox

<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">

<Button.Content>

<TextBox Name="Nume_buton" Text="OK" />

</Button.Content>

</Button>

Buton ce contine un patrat:

<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">

<Button.Content>

<Rectangle Height="100" Width="100" Fill="White"/>

</Button.Content>

</Button>

sau echivalent :

<Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”>

<Rectangle Height=”40” Width=”40” Fill=”Black”/>

</Button>

Colectie de articole

XAML permite sa adaugam articole la cele doua tipuri de colectii ce suporta indexarea: liste si dictionare.

Liste

O lista este orice colectie ce implementeaza System.Collections.List (de ex ArrayList).

Urmatorul cod adauga doua articole la un ListBox a carui proprietate Items este un ItemCollection ce implementeaza IList.

<ListBox xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”>

<ListBox.Items>

<ListBoxItem Content=”Item 1”/>

<ListBoxItem Content=”Item 2”/>

</ListBox.Items>

</ListBox>

Acest lucru e echivalent cu codul C# :

(15)

System.Windows.Controls.ListBox listbox = new System.Windows.Controls.ListBox();

System.Windows.Controls.ListBoxItem item1 =

new System.Windows.Controls.ListBoxItem();

System.Windows.Controls.ListBoxItem item2 =

new System.Windows.Controls.ListBoxItem();

item1.Content = "Item 1";

item2.Content = "Item 2";

listbox.Items.Add(item1);

listbox.Items.Add(item2);

sau in XAML echivalent putem scrie :

<ListBox xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”>

<ListBoxItem Content=”Item 1”/>

<ListBoxItem Content=”Item 2”/>

</ListBox>

Dictionare

System.Windows.ResourceDictionary este un tip de colectie folosita de obicei in WPF.

Aceasta implementeaza IDictionary, deci suporta adaugare, stergere si enumerare de perechi (cheie, valoare) in codul procedural.

In XAML puetm adauga perechi (cheie, valoare) la orice colectie ce implementeaza IDictionary.

Exemplu : adauga doua culori la ResourceDictionary.

<ResourceDictionary

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”>

<Color x:Key=”1” A=”255” R=”255” G=”255” B=”255”/>

<Color x:Key=”2” A=”0” R=”0” G=”0” B=”0”/>

</ResourceDictionary>

Echivalentul C# este:

System.Windows.ResourceDictionary d = new System.Windows.ResourceDictionary();

System.Windows.Media.Color color1 = new System.Windows.Media.Color();

System.Windows.Media.Color color2 = new System.Windows.Media.Color();

color1.A = 255; color1.R = 255; color1.G = 255; color1.B = 255;

color2.A = 0; color2.R = 0; color2.G = 0; color2.B = 0;

d.Add("1", color1);

d.Add("2", color2);

(16)

Valoare ce poate fi convertita la elementul obiect

Existenta converterilor face posibila existenta urmatorului cod.

Exemplu

<SolidColorBrush>White</SolidColorBrush>

echivalent cu

<SolidColorBrush Color=”White”/>

chiar daca Color nu a fost proiectata ca o proprietate pentru continut.

Spatii de nume proprii – declaratie Sintaxa este urmatoarea:

xmlns=”clr-namespace:<nume_tip>; assembly=<nume_assembly>”

De exemplu, pentru a seta valoarea unei proprietati la null putem scrie:

<MyObject xmlns='clr-namespace:Samples;assembly=samples.dll'>

<Person FirstName='Megan' LastName='{x:Null}' />

</MyObject>

(17)

Cuvinte cheie XAML :

(18)

Observatie :

Trebuie sa declaram prefixul x pentru ca acest tag sa fie parsat. Prefixul x este alias pentru namespace.

<MyObject xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns='clr-namespace:Samples;assembly=samples.dll'>

<Person FirstName='Megan' LastName='{x:Null}' />

</MyObject>

Putem defini pentru orice assembly CLR (sau multime de assemblies) un nume bazat pe URI.

<!-- option 1: import by CLR namespace -->

<Window

xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'

xmlns='clr-amespace:System.Windows; assembly=presentationframework.dll'>

</Window>

<!-- option 2: import by URI -->

<Window

xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'

xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>

</Window>

Cele doua definitii sunt echivalente.

(19)

WPF – Fundamente

Ierarhia de clase (cea mai des folosita) :

Object – clasa de baza pentru toate clasele din .NET.

DispatcherObject – clasa de baza folosita de orice obiect ce doreste sa fie accesat numai din firul care l-a creat.

DependencyObject – clasa de baza pentru orice obiect ce suporta proprietati dependente, una din caracteristicile principale ale WPF.

Freezable – clasa de baza pentru obiecte ce pot fi « inghetate » intr-o stare read-only din motive de performanta. Poate fi accesata de fire multiple. Nu-si poate schimba starea dar poate fi clonata. Exemple : primitive grafice – pensoane, penite, clase pentru geometrii si animatii.

Visual – clasa de baza pentru obiecte ce au reprezentare vizuala 2D.

UIElement – clasa de baza pentru toate obiectele vizuale 2D ce suporta evenimente rutate, asociere de comenzi, layout si focus.

Visual3D – clasa de baza pentru toate obiectele ce au reprezentare vizuala 3D.

UIElement3D – clasa de baza pentru toate obiectele vizuale 3D ce suporta evenimente rutate, asociere de comenzi, focus.

ContentElement – O clasa de baza similara cu UIElement dar pentru parti de document ale continutului ce nu au o redare proprie. ContentElement este gazduit intr-o clasa derivata din Visual pentru a fi redata pe ecran.

FrameworkElement - clasa de baza ce adauga suport pentru stiluri, data binding, resurse si un mecanism pentru controalele windows cum ar fi tooltips si meniul contextual.

FrameworkContentElement – analog cu FrameworkElement pentru continut.

Control – clasa de baza pentru controalele obisnuite Button, ListBox si StatusBar. Adauga proprietati precum Foreground, Background si FontSize precum si abilitatea de a fi

restilizate.

Arbori logici si arbori vizuali

In WPF, interfata cu utilizatorul este construita dintr-o arborescenta de obiecte cunoscuta sub numele de arbore logic ( in engleza « logical tree »).

Exemplu (din Adam Nathan - WPF 4 Unleashed).

<Window xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

Title=”About WPF 4 Unleashed” SizeToContent=”WidthAndHeight”

Background=”OrangeRed”>

<StackPanel>

<Label FontWeight=”Bold” FontSize=”20” Foreground=”White”>

WPF 4 Unleashed

</Label>

<Label>© 2019 SAMS Publishing</Label>

<Label>Installed Chapters:</Label>

<ListBox>

<ListBoxItem>Chapter 1</ListBoxItem>

<ListBoxItem>Chapter 2</ListBoxItem>

</ListBox>

<StackPanel Orientation=”Horizontal” HorizontalAlignment=”Center”>

<Button MinWidth=”75” Margin=”10”>Help</Button>

(20)

<Button MinWidth=”75” Margin=”10”>OK</Button>

</StackPanel>

<StatusBar>

You have successfully registered this product.

</StatusBar>

</StackPanel>

</Window>

Window este radacina.

Contine un StackPanel ca element descendent care la randul lui contine ... (urmariti codul).

Codul XAML de mai sus produce urmatoarea fereastra (in Kaxaml) :

Observatie

Arborele logic exista chiar si pentru interfetele ce nu sunt create in XAML.

Multimea elementelor ce sunt redate pe ecran constituie arborele de vizualizare (in engleza

« visual tree »).

Arborele vizual expune detaliile vizuale.

Button este in mod logic un singur control. Redarea lui pe ecran inseamna folosirea mai multor primitive WPF : Border, Background, etc.

Arborele logic si cel de vizualizare pot fi traversati folosind clasele

System.Windows.LogicalTreeHelper si

System.Windows.Media.VisualTreeHelper.

Exemplu

using System;

using System.Diagnostics;

using System.Windows;

using System.Windows.Media;

public partial class AboutDialog : Window {

public AboutDialog() {

InitializeComponent();

PrintLogicalTree(0, this);

}

Label

ListBox Button StatusBar

Title

StackPanel

(21)

protected override void OnContentRendered(EventArgs e) {

base.OnContentRendered(e);

PrintVisualTree(0, this);

}

void PrintLogicalTree(int depth, object obj) {

// Print the object with preceding spaces // that represent its depth

Debug.WriteLine(new string(‘ ‘, depth) + obj);

// Sometimes leaf nodes aren’t DependencyObjects (e.g. strings) if (!(obj is DependencyObject)) return;

// Recursive call for each logical child

foreach (object child in LogicalTreeHelper.GetChildren(

obj as DependencyObject)) PrintLogicalTree(depth + 1, child);

}

void PrintVisualTree(int depth, DependencyObject obj) {

// Print the object with preceding spaces // that represent its depth

Debug.WriteLine(new string(‘ ‘, depth) + obj);

// Recursive call for each visual child

for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj);

i++)

PrintVisualTree(depth + 1, VisualTreeHelper.GetChild(obj, i));

} }

Proprietati dependente. Proprietati atasate.

Clasa DependencyObject. Clasa DependencyProperty.

Clasa DependencyObject permite servicii pe proprietatea sistem. Rolul proprietatii sistem este de a calcula valorile proprietatilor si de a furniza o notificare despre schimbarea valorilor.

O alta clasa importanta este DependencyProperty ce permite inregistrarea proprietatilor dependente in proprietatea sistem si identificarea acestora.

Clasa DependencyObject, clasa de baza pentru alte clase, permite instantelor claselor derivate din aceasta sa foloseasca proprietati dependente.

Caracteristicile acestei clase - DependencyObject - sunt:

 Suport pentru gazduirea proprietatii dependente. Proprietatea dependenta se

inregistreaza folosind metoda statica Register si memorand valoarea returnata ca un camp "public static" in clasa noastra.

 Suport pentru gazduirea proprietatilor atasate, inregistrate cu metoda

RegisterAttached si memorand valoarea returnata ca un camp public static readonly in clasa noastra. Proprietatea atasata poate fi setata pe orice clasa derivata din DependencyObject.

 Furnizeaza metode pentru get, set si stergere valori pentru orice proprietate dependenta ce exista pe DependencyObject.

(22)

 Clasa de baza pentru ContentElement, Freezable sau Visual.

Proprietati dependente

O proprietate dependenta depinde de furnizori multipli pentru a-si determina valoarea sa la orice moment de timp. Acesti furnizori pot fi elemnete ale clasei parinte ale caror valori se propaga catre copii.

Proprietatile dependente sunt asemanatoare cu proprietatile CLR, dar conceptul din spatele lor este mai complex si mai puternic.

Principala diferenta este ca valoarea unei proprietati dependente, DependencyProperty, este rezolvata in mod dinamic cand se apeleaza metoda GetValue(), metoda mostenita din

DependencyObject, in timp ce pentru o proprietate .NET normala, valoarea este citita in mod direct din campul privat existent la nivel de clasa.

Clasa DependencyProperty

Reprezinta o proprietate ce poate fi setata prin metode utilizate in stilizare, data binding, animatie si mostenire.

Clasele derivate din DependencyObject pot contine proprietati dependente.

// MSDN

Metoda pentru inregistrarea unei proprietati dependente este Register (metoda statica) cu urmatoarele prototipuri (3 , 4 si 5 parametri – am ales cea cu 5 parametri) ce returneaza DependencyProperty :

public static DependencyProperty Register(

string name,

Type propertyType, Type ownerType,

PropertyMetadata typeMetadata,

ValidateValueCallback validateValueCallback )

Inregistreaza o proprietate dependenta : 1. cu numele specificat , 2. tipul proprietatii, 3. proprietarul proprietatii, 4. metadata proprietatii,

5. si o metoda callback, de validare pentru proprietate.

De interes este parametrul al 4 lea : PropertyMetadata care poate fi inlocuit si cu FrameworkPropertyMetadata derivata din UIPropertyMetadata.

Ierarhia de clase este :

PropertyMetadata

UIPropertyMetadata

FrameworkPropertyMetadata

(23)

Sintaxa cea mai complexa pentru ctor PropertyMetadata este :

//

// Summary:

// Initializes a new instance of the System.Windows.PropertyMetadata // class with the specified default value and callbacks.

//

// Parameters:

// defaultValue:

// The default value of the dependency property, usually provided // as a value of some specific type.

//

// propertyChangedCallback:

// Reference to a handler implementation that is to be

// called by the property system whenever the effective value // of the property changes.

//

// coerceValueCallback:

// Reference to a handler implementation that is to be called // whenever the property system calls

System.Windows.DependencyObject.CoerceValue(

System.Windows.DependencyProperty) // against this property.

//

// Exceptions:

// System.ArgumentException:

// defaultValue cannot be set to the value // System.Windows.DependencyProperty.UnsetValue;

// see Remarks.

public PropertyMetadata(

object defaultValue,

PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback);

Daca utilizam FrameworkPropertyMetadata ca parametrul 4 la Register, atunci avem posibilitatea de a seta si o comportare a proprietatii dependente.

Unul din ctori (cel mai complex) pentru aceasta clasa are prototipul:

Summary:

Initializes a new instance of the System.Windows.FrameworkPropertyMetadata class with the provided default value and framework metadata options,

specified callbacks, a Boolean that can be used to prevent animation of the property, and a data-binding update trigger default.

Parameters:

defaultValue:

The default value of the dependency property, usually provided as a specific type.

flags:

The metadata option flags (a combination of

System.Windows.FrameworkPropertyMetadataOptions values).

These options specify characteristics of the dependency property that interact with systems such as layout or data binding.

propertyChangedCallback:

A reference to a handler implementation that the property system will call whenever the effective value of the property changes.

(24)

coerceValueCallback:

A reference to a handler implementation that will be called whenever the property system calls

System.Windows.DependencyObject.CoerceValue(

System.Windows.DependencyProperty) against this property.

isAnimationProhibited:

true to prevent the property system from animating the property that this metadata is applied to. Such properties will raise a run-time exception originating from the property system if animations of them are attempted.

The default is false.

defaultUpdateSourceTrigger:

The System.Windows.Data.UpdateSourceTrigger to use when bindings for this property are applied that have their

System.Windows.Data.UpdateSourceTrigger

set to System.Windows.Data.UpdateSourceTrigger.Default.

//

// Exceptions:

// System.ArgumentException:

// defaultValue is set to

// System.Windows.DependencyProperty.UnsetValue; see // Remarks.

public FrameworkPropertyMetadata(

object defaultValue,

FrameworkPropertyMetadataOptions flags, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback, bool isAnimationProhibited,

UpdateSourceTrigger defaultUpdateSourceTrigger);

Valorile pentru flag afecteaza comportarea proprietatii dependente. Valorile posibile sunt :

Specifies the types of framework-level property behavior that pertain to a particular dependency property in the Windows Presentation Foundation (WPF) property system.

[Flags]

public enum FrameworkPropertyMetadataOptions {

No options are specified; the dependency property uses the default behavior of the Windows Presentation Foundation (WPF) property system.

None = 0,

The measure pass of layout compositions is affected by value changes to this dependency property.

AffectsMeasure = 1,

The arrange pass of layout composition is affected by value changes to this dependency property.

AffectsArrange = 2,

The measure pass on the parent element is affected by value changes to this dependency property.

AffectsParentMeasure = 4,

The arrange pass on the parent element is affected by value changes to this dependency property.

AffectsParentArrange = 8,

(25)

Some aspect of rendering or layout composition (other than measure or arrange) is affected by value changes to this dependency property.

AffectsRender = 16,

The values of this dependency property are inherited by child elements.

Inherits = 32,

The values of this dependency property span separated trees for purposes of property value inheritance.

OverridesInheritanceBehavior = 64,

Data binding to this dependency property is not allowed.

NotDataBindable = 128,

The System.Windows.Data.BindingMode for data bindings on this dependency property defaults to System.Windows.Data.BindingMode.TwoWay.

BindsTwoWayByDefault = 256,

The values of this dependency property should be saved or restored by journaling processes, or when navigating by Uniform resource identifiers (URIs).

Journal = 1024,

The subproperties on the value of this dependency property do not affect any aspect of rendering.

SubPropertiesDoNotAffectRender = 2048, }

Valoarea Inherits creaza posibilitatea ca aceasta proprietate dependenta sa poata sa-si propage valoarea catre elemnete descendente.

Observatie

Cand o anumita proprietate dependenta nu-si propaga valorile catre descendenti va trebui sa cercetam in documentatie daca acest flag are bitul corespunzator Inherits setat.

// end MSDN

Constructie clasa cu proprietate dependenta

Pentru clasa Persoana vom construi o proprietate dependenta– numita LastName – si un wrapper pentru aceasta proprietate.

Atentie la clasa DependencyObject.

public class Persoana : DependencyObject {

public static readonly DependencyProperty LastNameProperty = DependencyProperty.Register(

"LastName", typeof(string),

typeof(Persoana));

public string LastName {

get {

return (string)GetValue(LastNameProperty);

(26)

} set {

SetValue(LastNameProperty, value);

} } }

Numele dat proprietatii trebuie sa-l inregistram – LastName - , furnizam tipul mentinut de aceasta proprietate – string – si apoi furnizam tipul de obiect la care se ataseaza aceasta proprietate – Persoana.

Observatie:

In get / set nu se pune cod de validare. Cand valoarea unei proprietati dependente se schimba din XAML, se va apela direct SetValue si nu set definita mai sus.

Trasatura cea mai importanta este aceea ca aceasta proprietate furnizeaza o notificare la schimbarea valorii si aceasta notificare se propaga la descendentii clasei.

Proprietatile pot fi setate in XAML fara a fi necesar un cod procedural.

Vom urmari in continuare:

notificari pentru o proprietate dependenta;

proagarea valorilor;

furnizori multipli pentru o proprietate dependenta.

Vom incepe prin a vedea cum se implementeaza o proprietate dependenta.

De aceasta data se furnizeaza valoarea implicita si metoda callback.

public class Button : ButtonBase {

// Proprietatea dependenta

public static readonly DependencyProperty IsDefaultProperty;

static Button() {

// Inregistrare proprietate

Button.IsDefaultProperty = DependencyProperty.Register(

“IsDefault”,

typeof(bool), typeof(Button), new FrameworkPropertyMetadata(

false,

new PropertyChangedCallback(OnIsDefaultChanged)) );

}

// Un wrapper pentru proprietatea .NET (optional) public bool IsDefault

{

get { return (bool)GetValue(Button.IsDefaultProperty); } set { SetValue(Button.IsDefaultProperty, value); } }

// O metoda callback pentru schimbarea proprietatii (optional) private static void OnIsDefaultChanged(

DependencyObject o,

DependencyPropertyChangedEventArgs e) { … }

(27)

}

Discutie

Campul static si readonly, IsDefaultProperty, este proprietatea dependenta. Se declara static si readonly si este de tip DependencyProperty. Este sufixat cu “Property”.

Se inregistreaza aceasta proprietate cu metoda statica DependencyProperty.Register. Numele proprietatii va fi IsDefault, de tip bool si proprietarul proprietatii este clasa Button. Se inregistreaza metoda ce va fi apelata cand proprietatea isi schimba valoarea, ultimul parametru din ctor pentru FrameworkPropertyData.

Atentie mare la modul cum se implementeaza aceasta proprietate get/set. Obligatoriu

GetValue si SetValue. In implementare numele proprietatii este IsDefault. Descendentii o vor cauta dupa numele IsDefaultProperty.

In get / set nu se scrie alt cod – de verificare sau altceva. XAML apeleaza direct GeTvalue si/sau SetValue. Codul pentru verificari poate fi scris in metoda callback.

Implementare metoda callback, OnIsDefaultChanged, apelata cand proprietatea isi schimba valoarea. Metoda are doi parametri: unul de tip DependencyObject si unul derivat din EventArgs.

Notificare schimbare

Cand valoarea unei proprietati dependente se schimba, WPF poate genera in mod automat actiuni ce depind de proprietatile metadatei. Aceste actiuni pot fi de redesenare a unor

elemente, actualizarea layout-ului, reimprospatarea datelor asociate cu anumite controale, etc.

Acest mecanism de notificare este cunoscut si sub numele de “property trigger” si nu necesita cod procedural.

Scenariu

Consideram un buton care sa-si schimbe culoarea cand are mouse-ul deasupra.

Metoda 1

Vom trata evenimentele MouseEnter si MouseLeave.

<Button MouseEnter=”Button_MouseEnter” MouseLeave=”Button_MouseLeave”

MinWidth=”75” Margin=”10”>Help</Button>

<Button MouseEnter=”Button_MouseEnter” MouseLeave=”Button_MouseLeave”

MinWidth=”75” Margin=”10”>OK</Button>

iar metodele pentru evenimente sunt :

// Schimb Foreground in “blue” cand mouse-ul este pe buton void Button_MouseEnter(object sender, MouseEventArgs e) {

Button b = sender as Button;

if (b != null)

b.Foreground = Brushes.Blue;

}

// Restaurez Foreground la “black” (pensula originala) // cand mouse paraseste butonul

(28)

void Button_MouseLeave(object sender, MouseEventArgs e) {

Button b = sender as Button;

if (b != null)

b.Foreground = Brushes.Black;

}

Metoda 2

Folosind proprietatea Trigger, in XAML putem scrie :

<Trigger Property="IsMouseOver" Value="True">

<Setter Property="Foreground" Value="Red"/>

</Trigger>

Observatie:

Cand mouse-ul este deasupra butonului, proprietatea IsMouseOver devine true, iar proprietatea Foreground va fi setata cu valoarea Red. Cand mouse-ul paraseste butonul, WPF aduce butonul la starea initiala (Foreground) iar proprietatea IsMouseOver devine false.

Ceea ce trebuie sa facem este sa atribuim Trigger la fiecare buton, mai precis pe stilul butonului.

<Button

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

MinWidth=”75”

Margin=”30”>

<Button.Style>

<Style TargetType="{x:Type Button}"> <!—Destinatia -->

<Style.Triggers>

<Trigger Property="IsMouseOver" Value="True">

<Setter Property="Foreground" Value="Red"/>

</Trigger>

</Style.Triggers>

</Style>

</Button.Style>

OK <!-- Continut buton -->

</Button>

Pe langa “property trigger”, WPF suporta “data trigger” si “event trigger”.

Data trigger este o proprietate ce lucreaza pentru toate proprietatile .NET (nu numai pentru proprietati dependente). Modificarile unei date pot afecta alte controale din interfata.

Clasa DataTrigger. Este legata si de asocierea datelor la controale (data binding).

Clasa DataTrigger reprezinta un trigger ce aplica valorile proprietatii sau executa actiuni cand data asociata indeplineste anumite conditii.

Event trigger – permite sa specificam in mod declarativ actiunile ce vor fi executate cand apare un eveniment.

(29)

Mostenirea (propagarea) valorii unei proprietati

Nu e mostenirea clasica, ci modul de propagare a valorii proprietatii in arborele de vizualizare.

Sa urmarim exemplul ce urmeaza.

La nivel de fereastra <Window/> se defineste proprietatea FontSize="30" si

FontStyle="Italic". Acest lucru inseamna ca toate controalele din fereastra (fereastra este un container) ce expun text vor folosi marimea fontului ca fiind 30 si stilul fontului "Italic".

Daca alte controale din aceasta fereastra au setata proprietatea FontSize sau FontStyle, vor folosi acea valoare si nu cea definita in <Window />.

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

Title="About WPF 4 Unleashed" SizeToContent="WidthAndHeight"

Background="OrangeRed"

FontSize="30" FontStyle="Italic"> <!—aici e modificarea pentru FontSize -->

<StackPanel>

<Label FontWeight="Bold" FontSize="20" Foreground="White">

<!—- nu schimba FontSize -->

WPF 4 Unleashed </Label>

<Label>© 2019 SAMS Publishing</Label>

<Label>Installed Chapters:</Label>

<ListBox>

<ListBoxItem>Chapter 1</ListBoxItem>

<ListBoxItem>Chapter 2</ListBoxItem>

</ListBox>

<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">

<Button MinWidth="75" Margin="10">Help</Button>

<Button MinWidth="75" Margin="10">OK</Button>

</StackPanel>

<StatusBar>You have successfully registered this product.</StatusBar>

</StackPanel>

</Window>

Controalele se aliniaza la marimea ferestrei parinte deoarece fereastra parinte are setata proprietatea SizeToContent = "WidthAndHeight".

Daca un control are proprietatea FontSize setata atunci acel control foloseste acea valoare, nu mosteneste valoarea din parinte. Vezi primul Label de dupa StackPanel.

(30)

Observatie

StatusBar este neafectata de aceasta schimbare in controlul parinte.

Nu fiecare proprietate dependenta participa in cadrul acestei mosteniri. Intern, proprietatile dependente pot opta pentru mostenire pasand FrameworkPropertyMetadaOption.Inherits

in metoda Register.

Pot exista alte prioritati – mai mari – ce seteaza valoarea proprietatii.

StatusBar, Menu si ToolTip, intern folosesc proprietatile fontului sistem, deci ceea ce setam in Control Panel. Daca punem un buton in StatusBar acesta va avea fontul sistem.

Suport pentru provideri multipli

Figura urmatoare arata procesul din WPF executat pentru fiecare proprietate dependenta pentru a-i calcula valoarea finala. Procesul are loc automat si se bazeaza pe notificari.

Determina valoarea de baza => Evaluare (daca e o expresie) => Aplica animatii =>

Constrangeri (se apeleaza delegate CoerceValueCallbackdaca exista) =>

Validare (se apeleaza delegate ValidateValueCallback daca exista). Pas 1. Determina valoarea de baza.

Urmatorii furnizori pot seta valoarea (ordinea de precedenta de la cel mai prioritar catre cel mai putin prioritar !!??) :

1. Valoare locala

2. Trigger template parinte 3. Template parinte

4. Setari stiluri

5. Triggeri setari teme 6. Setter-i stil

(31)

7. Trigger stil teme 8. Setter-i stil teme

9. Mostenire valoare proprietate 10. Valoare implicita.

Observatie

Din strategia de determinare a valorii proprietatii dependente se observa ca valoarea implicita se aplica numai atunci cand nu exista setata o alta valoare.

Exemplu complet cu proprietate dependenta

Se creaza ierarhia de clase Figura <- Cerc (Cerc derivata din Figura).

In clasa Figura se defineste o proprietate dependenta numita Background, folosita pentru Brush - la umplerea unei figuri.

Clasa Figura este derivata din UIElement. Clasa Cerc expune proprietatile .NET

public string Name { get; set; } public int Raza {get; set;}

public System.Windows.Point Centru { get; set; } si are definiti doi constructori.

Constructorul fara parametru este necesar in XAML, iar celalalt constructor este folosit din cod C#.

Layout-ul pentru fereastra principala este un StackPanel. Pe langa alte controale definite in Windows vom folosi si instante ale clasei Cerc, pe care le vom desena in cadrul layout-ului.

Se trateaza evenimentul "clic stanga mouse" si se adauga noi instante ale clasei Cerc (metoda Mld din MainWindow.xaml.cs).

Tot codul este dat mai jos, inclusiv spatiile de nume.

(32)

//Fisierul Figura.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows;

using System.ComponentModel;

using System.Globalization;

using System.Drawing;

using Media=System.Windows.Media;

using Shapes=System.Windows.Shapes;

namespace WpfProprietatiDependente {

public class Figura: UIElement {

// Handle pentru fereastra. Va fi dat de fereastra unde // se afiseaza aceste obiecte.

// In acest exemplu nu e folosit public IntPtr Hwnd;

// Brush. Culoare verde : valoarea implicita

// Proprietatea dependenta Background folosita in XAML static FrameworkPropertyMetadata fpm =

new FrameworkPropertyMetadata(Media.Brushes.Green);

public static DependencyProperty BackgroundProperty = DependencyProperty.Register("Background", typeof(Media.Brush), typeof(Figura), fpm);

// Nu e folosita

public static DependencyProperty LineStyleProperty;

public Figura() {}

public Figura(IntPtr hwnd) {

Hwnd = hwnd;

}

// Necesar pentru apel proprietate din cod C#

public Media.Brush Background {

get { return GetValue(BackgroundProperty) as Media.Brush; } set { SetValue(BackgroundProperty, value); }

}

public virtual void Draw(){ } }

// Clasa Cerc

public class Cerc : Figura {

public string Name { get; set; } public int Raza {get; set;}

public System.Windows.Point Centru { get; set; }

Referințe

DOCUMENTE SIMILARE

In cazul in care operatorul == este aplicat asupra referintelor la obiecte, acesta stabileste daca cele doua referinte refera acelasi obiect. In cazul stringurilor,

 Dacă s și t sunt expresii pentru tipuri, atunci sxt este expresie pentru tip.  Expresiile pentru tip pot conține variabile ale căror valori sunt expresii

Pentru pacienţii la care rezultatele postoperatorii nu sunt satisfăcătoare ori care au simptomatologie sugestivă pentru ischemie miocardică se va efectua testul de efort şi

MATLAB lucreaza fie in modul linie de comanda, caz in care fiecare linie este prelucrata imediat si rezultatele sunt afisate, fie utilizand programe scrise in fisiere. Fisierele care

 Se foloseşte pentru a modela situaţiile între care un obiect este format din mai multe componente...  OMG Unified Modeling LanguageTM (OMG UML), Infrastructure, Version 2.2,

Daca destinatia este intr-o retea conectata direct cu G, atunci G foloseste o intrare care arata costul folosirii retelei, si faptul ca nu este folosita nici o gateway (poarta)

• Testarea aplicatiei pentru a verifica daca functionalitati existente sunt corecte dupa adaugarea de noi functionalitati in aplicatie. •

NULL GetMessage regaseste mesajele pentru orice fereastra ce apartine firului din care este apelata si mesaje &#34;puse&#34; (in coada.. de mesaje) cu ajutorul