Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12....

47
Windows Presentation Foundation – WPF (1) Programowanie Wizualne Paweł Wojciechowski Instytut Informatyki, Politechniki Poznańskiej 2012

Transcript of Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12....

Page 1: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Windows Presentation

Foundation – WPF (1)Programowanie Wizualne

Paweł Wojciechowski

Instytut Informatyki, Politechniki Poznańskiej

2012

Page 2: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Architektura

Managed WPF API

Media

Integration

Layer

Direct3D

milcore.dll WindowsCodecs.dll

PresentationFramework.dll

PresentationCore.dll WindowsBase.dll

User32

Page 3: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Hierarchia klas

object

DispatcherObject

DependencyObject

Visual

UIElement

FrameworkElement

Control

realizacja modelu STA (single thread affinity)

model właściwości – cechy: informowanie o zmianach, dziedziczenie wartości domyślnej

obiekt, który jest „rysowany” – transformacje, przycinanie, przezroczystość, hit tests

layout, inputs, events, data binding, animation, styles

kluczowe właściwości obiektów

obiekty interaktywne. Właściwości: font, foreground, background colors

Page 4: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Jednostki wielkości w WPF (1)

jednostki wielkości uwzględniają DPI ekranu

zaleta: na wszystkich ekranach wielkość elementu jest taki sam

wada: ...

Jednostka WPF = 1/96

Gdzie w systemie Windows ustawia się DPI?

𝑙𝑖𝑐𝑧𝑏𝑎 𝑝𝑖𝑘𝑠𝑒𝑙𝑖 𝑛𝑎 𝑗𝑒𝑑𝑛𝑜𝑠𝑡𝑘ę 𝑊𝑃𝐹 =𝑟𝑜𝑧𝑚𝑖𝑎𝑟 𝑠𝑡𝑎ł𝑒𝑗 𝑗𝑒𝑑𝑛𝑜𝑠𝑡𝑘𝑖 𝑊𝑃𝐹

𝐷𝑃𝐼 𝑚𝑜𝑛𝑖𝑡𝑜𝑟𝑎

𝑟𝑜𝑧𝑚𝑖𝑎𝑟 𝑒𝑙𝑒𝑚𝑒𝑛𝑡𝑢 𝑤 𝑝𝑖𝑘𝑠𝑒𝑙𝑎𝑐ℎ =𝑙𝑖𝑐𝑧𝑏𝑎 𝑝𝑖𝑘𝑠𝑒𝑙𝑖 𝑛𝑎 𝑗𝑒𝑑𝑛𝑜𝑠𝑡𝑘ę 𝑊𝑃𝐹

𝑀𝑜𝑗𝐸𝑙𝑒𝑚𝑒𝑛𝑡. 𝐴𝑐𝑡𝑢𝑎𝑙𝑊𝑖𝑑𝑡ℎ

Page 5: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Jednostki wielkości w WPF (2)

Page 6: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

WPF główne cechy

wspomaganie sprzętowe

wykorzystanie Direct3D

niezależność od rozdzielczości

wykorzystanie systemu DPI i ustawień systemowych

brak ustalonego wyglądu kontrolek

kontrolki są „lookless” – są w pełni konfigurowalne

deklarowane interfejsy użytkownika

interfejs użytkownika deklarowany jest w specjalnym języku XAML

Page 7: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

XAML

XAML Extensible Application Markup Language

case sensitive

główny cel – oddzielenie logiki aplikacji od jej wyglądu

XAML nie jest niezbędny do działania WPFa

Kompilacja -> BAML (Binary Application Markup Language)

Podstawowe właściwości:

Każdy element zdefiniowany w XAMLu odpowiada klasie w .NET.

Jak w każdym dokumencie XML jeden element można osadzać w innym

Właściwości klas mogą zostać ustawione poprzez atrybuty.

Page 8: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Pierwsza aplikacja

<Window x:Class="WpfApplication1.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>

namespace WpfApplication1{

/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{

public MainWindow(){

InitializeComponent();}

}}

Plik xaml:

Plik cs:

Page 9: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Przestrzenie nazw

„Namiary” na lokację klas .NET – atrybut xmlns

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

domyślny pakiet w aplikacji zawierający wszystkie klasy WPF.

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

pakiet zawierający różne narzędzia umożliwiające wpłynięcie na sposób

interpretacji dokumentu XAML

Odwołanie do własnych klas

xmlns:prefix="clr-namespace:Namespace;assembly=AssemblyName"

<Page x:Class="WPFApplication1.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:custom="clr-namespace:Sample;assembly=SampleLibrary">...

<custom:ExampleClass/>...

</Page>

Page 10: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Nazywanie elementów interfejsu

Nadawanie nazw elementom nie jest obowiązkowe.

Wymagane jest jednak jeśli wymagane są zmiany parametrów elementu

kontrolnego w kodzie programu

Dla tak zdefiniowanej nazwy zostanie wygenerowana automatycznie następująca część kodu klasy MainWindow

<Grid>...

</Grid>

<Grid Name="Grid_1">...

</Grid>

#line 5 "..\..\..\MainWindow.xaml"[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]internal System.Windows.Controls.Grid Grid_1;

Page 11: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Właściwości komponentów proste typy i konwertery

<Image Height="250" HorizontalAlignment="Left" Name="image1" Stretch="None"VerticalAlignment="Top" Width="250"Source="/WpfApplication1;component/Images/bitmap.jpg" />

Dla powyższego komponentu (Image) muszą być zdefiniowane następujące właściwości: Height, HorizontalAlignment, Stretch, VerticalAlignment, Width, Soruce

Typy proste – prosta konwersja.Typy złożone np. właściwość Background wymaga specjalnego konwertera.

Zaleca się nadawania wartości parametrów w XAMLu nie w kodzie aplikacji, ze względu na to,

iż XAML jest parsowany i sprawdzany w czasie kompilacji, dzięki czemu wcześniej można wykryć

potencjalne błędy.

Page 12: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Właściwości komponentówwłaściwości złożone

niektóre właściwości mogą być obiektami – problem z kowersją

w XAML-u można definiować elementy zagnieżdżone w formie Rodzic.NazwaWłaściwości

<Image Name="image1" Stretch="None" VerticalAlignment="Top" Width="250"><Image.Height>250</Image.Height><Image.HorizontalAlignment>Left</Image.HorizontalAlignment>

</Image>

<Image Height="250" HorizontalAlignment="Left" Name="image1" Stretch="None"VerticalAlignment="Top" Width="250"/>

Page 13: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Właściwości komponentówwłaściwości złożone (2)

<Grid Name="Grid_1"><Grid.Background>

<RadialGradientBrush><GradientStop Offset="0.00" Color="White" /><GradientStop Offset="0.5" Color="Red"/><GradientStop Offset="0.75" Color="Indigo"/><GradientStop Offset="1" Color="Violet"/>

</RadialGradientBrush></Grid.Background>

</Grid>

Page 14: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

RadialGradientBrush rgb = new RadialGradientBrush();

GradientStop gradientStop1 = new GradientStop();gradientStop1.Color = Colors.White;gradientStop1.Offset = 0;rgb.GradientStops.Add(gradientStop1);

GradientStop gradientStop2 = new GradientStop();gradientStop2.Color = Colors.Red;gradientStop2.Offset = 0.5;rgb.GradientStops.Add(gradientStop2);

GradientStop gradientStop3 = new GradientStop();gradientStop3.Color = Colors.Indigo;gradientStop3.Offset = 0.75;rgb.GradientStops.Add(gradientStop3);

GradientStop gradientStop4 = new GradientStop();gradientStop4.Color = Colors.Violet;gradientStop4.Offset = 1;rgb.GradientStops.Add(gradientStop4);

Grid_1.Background = rgb;

Page 15: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Właściwości komponentówDynamiczne wartości właściwości

w poprzednich przykładach wartości właściwości były statyczne

Specjalna składnia umożliwia nadawanie wartości dynamicznych przez

wiązanie jej z wartościami właściwości klas

wszystkie rozszerzone znaczniki (markup extensions) są zaimplementowane w klasach dziedziczących po System.Windows.Markup.MarkupExtension

<Label Name="label1" Content="Hello World" Background="{x:Static SystemColors.HighlightColor}"/>

label1.Background = new SolidColorBrush(SystemColors.HighlightColor);

<Label Name="label1" Content="Hello World"><Label.Background>

<SolidColorBrush><SolidColorBrush.Color>

<x:Static Member="SystemColors.HighlightColor"></x:Static></SolidColorBrush.Color>

</SolidColorBrush></Label.Background>

</Label>

Page 16: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Właściwości komponentówwłaściwości powiązane

Attached Properties

właściwości zdefiniowane w jednym z komponentów, ale zdefiniowane w

innej klasie

używanie poprzez: TypDefniniujący.NazwaWłaściwości

są one przekształcane w wywołania metod

TypDefiniujący.SetNazwaWłaściwości

<Label Name="label1" Content="Hello World" Grid.Row="0" Grid.Column="0"/>

Grid.SetColumn(label1, 1);

Page 17: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Elementy zagnieżdżone

element musi zadecydować w jaki sposób obsługiwać elementy zagnieżdżone.

Dzieje się to za pomocą jednego z trzech mechanizmów:

Jeżeli rodzic implementuje interfejs IList, wywoływana jest metoda

IList.Add()

Jeżeli rodzic implementuje IDictionary, wywoływana jest metoda

IDictionary.Add() elementy muszą mieć nadaną wartość parametru x:Key

Jeżeli rodzicowi nadano atrybut ContentProperty, dziecko używane jest do

nadania wartości wskazanej właściwości.

<Button>Ala ma kota

</Button>

Page 18: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Zdarzenia

w XAMLu można również definiować zdarzenia –NazwaZdarzenia="NazwaMetodyObsługiZdarzenia"

<Button Content="Button" Name="button1" Click="button1_Click" />

private void button1_Click(object sender, RoutedEventArgs e){

MessageBox.Show("Ala ma kota");}

Page 19: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Ładowanie i kompilacja XAML

Implementacja aplikacji w WPFie może być realizowana za pomocą

następujących metod:

tylko kodu – definicja całego interfejsu za pomocą kodu np. w C#

Kodu i plików XAML – podejście stosowane w przypadku dynamicznie zmieniających

się interfejsów. Plik XAML jest ładowany podczas uruchomienia programu za

pomocą klasy XamlReader z przestrzeni nazw System.Windows.Markup

Kodu i plików BAML – najczęściej stosowane podejście. Interfejs opisany jest w

plikach XAML, które są kompilowane do BAML i osadzane w pakiecie.

Page 20: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Rozmieszczenie komponentówLayouts

Page 21: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Filozofia rozmieszczania komponentów

odejście od sztywnych ustawień pozycji i rozmiaru

okno WPF może zawierać tylko jeden komponent

zasady budowania interfejsów:

elementy kontrolne nie powinny mieć ustawionego rozmiaru – powinny one

wypełniać pojemnik w którym się znajdują

można ograniczać minimalny i maksymalny rozmiar komponentów

położenie elementów nie jest opisane współrzędnymi ekranu, ale rozmiarem,

rozkładem itp. pojemnika(ów) w których się znajdują. Przerwy pomiędzy

komponentami narzuca się poprzez wartości parametru Margin.

pojemniki dzielą swoją przestrzeń pomiędzy swoje dzieci

pojemniki mogą być zagnieżdżone

Page 22: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Podstawowe rodzaje pojemników

StackPanel

WrapPanel

DockPanel

Grid

UniformGrid

Canvas

TabPanel, ToolbarPanel, ToolbarOverflowPanel, VirtualizingStackPanel,

InkCanvas

Page 23: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Layout - właściwości

HorizontalAlignment: Center, Left, Right, Stretch

VerticalAlignment: Center, Top, Bottom, Stretch

Margin

MinWidth/MinHeight

MaxWidth/MaxHeight

Width/Height

Właściwość Background musi zostać ustawiona (domyślnie null) jeśli pojemnik ma

otrzymywać zdarzenia myszy! Naturalnie może to być kolor transparentny.

Page 24: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

StackPanel

<StackPanel><Label>Stack Panel</Label><Button>Button 1</Button><Button>Button 2</Button><TextBox>TextBox 1</TextBox><Button>Button 3</Button><Button>Button 4</Button>

</StackPanel>

<StackPanel Orientation="Horizontal">...

</StackPanel>

Page 25: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

StackPanel (2)

<StackPanel Margin="3" Background="Aqua"><Label HorizontalAlignment="Center" Margin="3">Stack Panel</Label><Button HorizontalAlignment="Left" Margin="3">Button 1</Button><Button HorizontalAlignment="Right" Margin="3">Button 2</Button><TextBox Margin="3">TextBox 1</TextBox><Button HorizontalAlignment="Center" Margin="3">Button 3</Button><Button Margin="3">Button 4</Button>

</StackPanel>

Page 26: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Wyznaczanie wielkości komponentów

Rozmieszczenie elementów pojemnika składa się z dwóch etapów:

pomiaru (measure stage) – pojemnik „pyta” swoje dzieci o ich preferowany rozmiar

rozmieszczenia (arrange stage) – dzieci są rozmieszczane w pojemniku na właściwych pozycjach

Pojemniki nie wspierają przewijania (scrolls). Jest za to komponent – ScrollViewer.

Informacje wykorzystywane przy określaniu rozmiaru komponentu to:

Minimalny rozmiar – rozmiar komponentu będzie co najmniej taki, jak jego minimalny rozmiar

Maksymalny rozmiar – rozmiar komponentu będzie mniejszy od jego maksymalnego rozmiaru (chyba, że minSize > maxSize)

Zawartość – jeśli zawartość komponentu będzie wymagała większego rozmiaru, to zostanie on powiększony (DesiredSize)

Wielkość pojemnika – jeżeli wielkość pojemnika jest mniejsza niż wielkość komponentu, to część komponentu zostanie obcięta

(Horizontal|Vertical)Alignment – pojemnik zwiększy rozmiar komponentu jeśli dla tej własności zostanie ustawiona wartość Stretch

Rozmiar komponentu może zostać odczytany z właściwości ActualWidth, ActualHeight(Width i Height mogą być = null !)

Page 27: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Rozmiar okna głównego

WPF dopuszcza sztywne ustawienie rozmiaru okna. Kiedy i dlaczego?

Aby rozmiar okna dostosowywał się do zawartości należy:

Usunąć właściwości Width i Height okna,

Ustawić Window.SizeToContent na (WidthAndHeight, Width lub Height)

Page 28: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

WrapPanel

rozmieszcza komponenty kolejno w jednym wierszu, a gdy zabraknie miejsca przechodzi do kolejnego wiersza (oczywiście dla WrapPanel.Orientation = Horizontal).

<WrapPanel ><Label MinHeight="60">Stack Panel</Label><Button VerticalAlignment="Top" >Button 1</Button><Button >Button 2</Button><TextBox >TextBox 1</TextBox><Button VerticalAlignment="Bottom" >Button 3</Button><Button VerticalAlignment="Center">Button 4</Button>

</WrapPanel>

Page 29: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

DockPanel

rozmieszcza komponenty wzdłuż krawędzi

kolejność dodawania komponentów jest istotna!

(Horizontal|Vertical)Alignment są brane pod uwagę

<DockPanel LastChildFill="True"><Label DockPanel.Dock="Left">Stack Panel</Label><Button DockPanel.Dock="Top">Button 1</Button><Button DockPanel.Dock="Right">Button 2</Button><TextBox DockPanel.Dock="Top" >TextBox 1</TextBox><Button DockPanel.Dock="Bottom">Button 3</Button><Button >Button 4</Button>

</DockPanel>

Page 30: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Grid

najbardziej zaawansowany pojemnik

tworzenie rozkładu za pomocą tego pojemnika przebiega dwuetapowo

Definicja wierszy (Grid.RowDefinitions) i kolumn (Grid.ColumnDefinitions)

Rozmieszczenie komponentów – właściwości Grid.Row i Grid.Column

domyślnie 1 komórka – 1 komponent

włożenie dwóch elementów do komórki powoduje ich nałożenie

Komponent UniformGrid – uproszczony Grid

Page 31: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Grid (2)

<Grid><Grid.RowDefinitions>

<RowDefinition /><RowDefinition />

</Grid.RowDefinitions><Grid.ColumnDefinitions>

<ColumnDefinition/><ColumnDefinition/><ColumnDefinition/>

</Grid.ColumnDefinitions>

<Label Grid.Row="0" Grid.Column="0" >Grid</Label><Button Grid.Row="0" Grid.Column="1">Button 1</Button><Button Grid.Row="0" Grid.Column="2">Button 2</Button><TextBox Grid.Row="1" Grid.Column="1">TextBox 1</TextBox><Button Grid.Row="1" Grid.Column="2"

HorizontalAlignment="Center"VerticalAlignment="Center">Button 3

</Button><Button Grid.Row="1" Grid.Column="0">Button 4</Button>

</Grid>

Page 32: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Grid – rozmiary wierszy i kolumn

rozmiary wierszy i kolumn podlegają jednej z następujących reguł, od której

zależy sposób obsługi zmiany rozmiaru komponentu w przypadku zwiększenia

rozmiaru pojemnika:

stały rozmiar – nieelastyczne

automatyczny – wiersz/kolumna dostają dokładnie tyle miejsca ile potrzebują

proporcjonalny – cały dostępny rozmiar jest proporcjonalnie dzielony przez

wiersze/kolumny – wartość domyślna

<RowDefinition Height="80"/>

<RowDefinition Height="Auto"/>

<ColumnDefinition Width="*"/><ColumnDefinition Width="2*"/><ColumnDefinition Width="Auto"/>

Page 33: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Grid – rozmiary wierszy i kolumn

<Grid.RowDefinitions><RowDefinition Height="80"/><RowDefinition Height="Auto"/>

</Grid.RowDefinitions><Grid.ColumnDefinitions>

<ColumnDefinition Width="*"/><ColumnDefinition Width="2*"/><ColumnDefinition Width="Auto"/>

</Grid.ColumnDefinitions>

Page 34: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Grid – „Rozpiętość” (Span) kolumn i

wierszy

<Grid>...<Label Grid.Row="0" Grid.Column="0" >Grid</Label><Button Grid.Row="0" Grid.Column="1"

Grid.ColumnSpan="2">Button 1</Button>

<TextBox Grid.Row="1" Grid.Column="1">TextBox 1

</TextBox><Button Grid.Row="1" Grid.Column="2"

HorizontalAlignment="Center"VerticalAlignment="Center">

Button 3</Button><Button Grid.Row="1" Grid.Column="0">Button 4</Button>

</Grid>

Page 35: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Grid – „paski podziału” (splitter bars)

umożliwia zmianę rozmiaru wierszy/kolumn użytkownikowi aplikacji

pasek podziału musi być umieszczony w komórce

rozmiar wiersza/kolumny powinien zostać ustawiony na stałe lub automatycznie

rozszerzana jest zawsze cała kolumna/wiersz, nawet jeśli GridSplitterzajmuje tylko jedną komórkę

domyślny rozmiar GridSplitter-a jest 0. Należy ustawić następujące właściwości:

Podział pionowy: Width, VerticalAlignment=Stretch i HorizontalAlignment=Center

Podział poziomy: Height, HorizontalAlignment=Stretch i VerticalAlignment=Center

Page 36: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

GridSplitter

<Grid><Grid.RowDefinitions>

<RowDefinition /><RowDefinition />

</Grid.RowDefinitions><Grid.ColumnDefinitions>

<ColumnDefinition /><ColumnDefinition Width="Auto"/><ColumnDefinition />

</Grid.ColumnDefinitions>

<Label Grid.Row="0" Grid.Column="0" >Grid</Label><Button Grid.Row="0" Grid.Column="2">Button 1</Button><Button Grid.Row="1" Grid.Column="2"

HorizontalAlignment="Center"VerticalAlignment="Center">Button 3</Button>

<Button Grid.Row="1" Grid.Column="0">Button 4</Button>

<GridSplitter Grid.Column="1" Grid.Row="0" Grid.RowSpan="1" Width="10„VerticalAlignment="Stretch" HorizontalAlignment="Center"/>

</Grid>

Page 37: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Canvas

umożliwia ręczne umiejscowienie elementów

pozycję podaje się w parametrach Canvas.Top (Canvas.Bottom) oraz

Canvas.Left (Canvas.Right)

Jeżeli elementy nachodzą na siebie, to parametrem Canvas.ZIndex można

definiować ich kolejność – element z wyższą wartości zawsze będzie znajdował się nad elementem z niższą wartością Zindex.

<Canvas><Button Canvas.Left="100" Canvas.Top="20">Button 1</Button><Button Canvas.Top="50" Canvas.Right="20" Width="100"

VerticalAlignment="Stretch"Canvas.ZIndex="1">Button 2</Button>

<Button Canvas.Top="60" Canvas.Right="40" Height="80">Button 3

</Button></Canvas>

Page 38: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Ramka - Border

<Border Margin="5"Padding="5"Background="LightYellow"BorderBrush="SteelBlue"BorderThickness="3,5,3,5"CornerRadius="3" >

<Grid>...

</Grid>

</Border>

Page 39: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

DependencyProperties

Page 40: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Podstawowe informacje

Dependency Property stanowi rozszerzenie pojęcia właściwości z .NETa na

potrzeby interfejsów użytkownika w WPF

Jest to podstawowy mechanizm wykorzystywany w animacji elementów

interfejsu, wiązaniu danych (data binding) oraz obsłudze styli

DP umożliwiają:

informowanie o zmianie wartości (change notification)

dziedziczenie wartości właściwości

zmniejszają koszty przechowywania wartości

Page 41: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Tworzenie Depencency Property

można je dodać tylko do obiektów dziedziczących po DependencyObject

obiekt DependencyProperty musi być zawsze statyczny i tylko do odczytu

obiekt ten należy zarejestrować przed jakimkolwiek użyciem klasy dla której

go definiujemy

public static readonly DependencyProperty AquariumGraphicProperty;

static MainWindow(){

AquariumGraphicProperty = DependencyProperty.Register("AquariumGraphic",typeof(Uri),typeof(MainWindow),new FrameworkPropertyMetadata(null,

FrameworkPropertyMetadataOptions.AffectsRender,new PropertyChangedCallback(OnUriChanged))

);}

Page 42: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Tworzenie Dependency Property (2)

Rejestrując DP należy podać:

jej nazwę

typ danych używany przez tę właściwość

typ danych, który będzie taką właściwość posiadał

opcjonalnie: obiekt FrameworkPropertyMetadata z dodatkowymi ustawieniami

opcjonalnie: funkcję zwrotną do walidacji wartości

Ustawienia FrameworkPropertyMetadata:

AffectsArrange,AffectsMeasure, AffectsParrentArrange, AffectsParentMeasure,

AffectsRender, BindsTwoWayByDefault, Inherits, IsAnimationProhibited,

IsNotDataBindable, DefaultValue, CoerceValueCallback, PropertyChangedCallback

Page 43: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Tworzenie Dependency Property (3)

dodanie wrapper-a właściwości

walidacja danych nie następuje w setterach/getterach!

właściwości mogą być współdzielone

Właściwości mogą być powiązane – użycie RegisterAttached()

Usuwanie wartości właściwości:

public Uri AquariumGraphic{

get { return (Uri)GetValue(AquariumGraphicProperty); }set { SetValue(AquariumGraphicProperty, value); }

}

Window1.ClearValue(MainWindow.AquariumGraphicProperty);

TextBlock.FontFamilyProperty = TextElement.FontFamilyProperty.AddOwner(typeof(TextBlock));

Page 44: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Wykorzystanie DP przez WPFinformowanie o zmianach (change notification)

DP nie uruchamia automatycznie zdarzeń w momencie zmiany wartości

Uruchamia metodę OnPropertyChangedCallback(), która to przekazuje

informację o zmianie wartości do dwóch serwisów: wiązania danych i

triggerów – chcąc reagować na zmianę wartości można albo utworzyć

wiązanie albo napisać trigger

Niektóre komponenty udostępniają zdarzenia po zmianie wartości np. ScrollBar – ValueChanged

Page 45: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Wykorzystanie DP przez WPFwyznaczanie wartości (dynamic value resolution)

Określenie bazowej wartości właściwości odbywa się na podstawie:

Wartości domyślnej,

Wartości dziedziczonej,

Wartości dla styli

lokalnej wartości

Następnie wartość końcowa określana jest w następujący sposób:

Jeżeli wartość opisana jest jakimś wyrażeniem – wyznaczenie jej wartości (data

binding i zasoby)

Jeżeli wartość jest celem animacji – zastosowanie animacji

Wywołanie metody CoerceValueCallback w celu „naprawienia” wartości

Page 46: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Walidacja wartości

Ustawienie wartości DP przebiega następująco:

Dostarczana wartość trafia do metody CoerceValueCallback, gdzie może zostać

zmodyfikowana. Jeśli zmiana jest nieakceptowalna zwracana jest wartość

DependencyProperty.UnsetValue

Następnie uruchamiana jest metoda ValidateValueCallback, która zwraca

wartość true jeśli wartość jest akceptowana. Metoda ta nie ma dostępu do

pozostałych właściwości obiektu.

Jeśli poprzednie kroki zakończą się sukcesem, zostaje wywołana metoda

PropertyChangedCallback

ValidateValueCallback musi być statyczna i jest dostarczana jako

opcjonalna na etapie rejestracji DP

CoerceValueCallback ma następujący nagłówek

private static object CoerceMaximum( DependencyObject d, object value);

Page 47: Windows Presentation Foundation (1)sirius.cs.put.poznan.pl/~inf94333/pw/WPF1.pdf · 2012. 12. 13. · Pierwsza aplikacja

Przykład działania walidacji

ScrollBar bar = new ScrollBar();bar.Value = 100;//bar.Value = 1bar.Minimum = 1;//bar.Value = 1bar.Maximum = 200;//bar.Value = 100