You are on page 1of 182

2 WPF, Just Code It!

Prakata

Pada saat pertama kali Anda membuka buku ini dan membaca prakata ini, maka hal
pertama yang hendak kami katakan adalah bahwa buku setebal 180 halaman ini adalah
buku yang jauh dari sempurna. Pembelajaran adalah sesuatu yang kontinyu dan
berkelanjutan dan buku ini hadir sebagai referensi yang menemani rekan-rekan
komunitas yang hendak mempelajari WPF.

Seperti apa yang kami katakan, buku ini adalah buku bertipe referensi, Anda akan
menemukan sekumpulan fakta di WPF, sekumpulan kode, dan sekumpulan jargon-
jargon tentang WPF, yang akan membuka khasanah Anda tentang WPF. Sebuah hal yang
hendak kami tekankan pada seri buku Just Code It®, adalah kami menekankan
penggunaan buku ini bersama-sama dengan training kit Visual Studio 2008 yang dapat
Anda unduh di situs Geeks dengan alamat

http://geeks.netindonesia.net/files/folders/trainingkit/default.aspx

Setelah mengunduh apa yang Anda lakukan, cukup dua langkah

 Pasang Training Kit tersebut, pelajari tentang WPF


 Temani pembelajaran Anda dengan buku ini.

Buku ini tiada akan hadir tanpa bantuan Findra, yang telah menggabungkan, menyusun,
dan menyempurnakan kaidah tata bahasanya. Seluruh anggota MIC-Gokilz. Mas Wely
yang selalu membantu dari sisi sumber daya dan semangat. Mas Naren yang selalu
menyempatkan waktu untuk mendengar, merasakan, dan memperhatikan setiap
langkah dan usaha pembuatan buku ini. Dan semua rekan-rekan yang tak dapat kami
sebut satu persatu.

Buku ini untuk Anda anggota komunitas, dan dari kami Anggota Komunitas

Salam Hangat,

Ridi Ferdiana | ridi@mvps.org


3 WPF, Just Code It!

Daftar Isi

1 Pengenalan WPF .............................................................................................................. 13


1.1 Tentang WPF ............................................................................................................13
1.2 Fitur-fitur WPF ..........................................................................................................15
1.2.1 Antarmuka Tampilan Grafis ..............................................................................15
1.2.2 Interoperabilitas ...............................................................................................15
1.2.3 Layanan Media ..................................................................................................16
1.2.4 Data binding ......................................................................................................16
1.2.5 Antarmuka Pengguna .......................................................................................16
1.2.6 Anotasi ..............................................................................................................17
1.2.7 Imaging .............................................................................................................17
1.2.8 Efek ...................................................................................................................18
1.2.9 Dokumen...........................................................................................................18
1.2.10 Teks ...................................................................................................................18
1.2.11 Input Alternatif .................................................................................................19
1.2.12 Aksesabilitas......................................................................................................19
1.3 Arsitektur WPF .........................................................................................................20
1.4 Kesimpulan ...............................................................................................................23
2 WPF Programming Model ................................................................................................ 25
2.1 XAML.........................................................................................................................25
2.2 Dasar Aplikasi WPF ...................................................................................................26
2.2.1 Jenis Aplikasi WPF .............................................................................................27
2.2.1.1 Windows Applications ..................................................................................27
2.2.1.2 Navigation Applications ................................................................................30
2.2.1.3 XBAP ..............................................................................................................30
2.2.1.3.1 XBAP dan Halaman Web .........................................................................31
2.2.1.3.2 XBAP dan Isolated Storage ......................................................................32
2.2.2 Aplikasi WPF dan Keamanan ............................................................................33
2.2.3 Mengkonfigurasi Navigasi Berbasis Halaman ...................................................33
4 WPF, Just Code It!

2.2.3.1 Menggunakan Pages .....................................................................................33


2.2.3.2 Meletakkan Pages didalam Frames ..............................................................33
2.2.3.3 Menggunakan Hyperlinks .............................................................................34
2.2.3.3.1 Menetapkan Properti NavigateUri Secara Dinamis ................................35
2.2.3.3.2 Navigasi Fragment...................................................................................35
2.2.3.4 Menggunakan NavigationService .................................................................35
2.2.4 Menggunakan Jurnal.........................................................................................37
2.2.4.1 Menghapus Item dari Jurnal .........................................................................37
2.2.4.2 Menambahkan Item ke Jurnal ......................................................................38
2.2.5 Menangani Navigation Events ..........................................................................39
2.2.5.1 Melewatkan Informasi ke Event-Event Navigasi ..........................................40
2.2.5.2 Membatalkan Navigasi..................................................................................41
2.2.6 Menggunakan Obyek-obyek PageFunction ......................................................41
2.2.6.1 Menghapus Entri-entri PageFunction dari Jurnal .........................................43
2.2.7 Navigasi Sederhana dan Navigasi Terstruktur ..................................................43
2.3 Mengelola Kemampuan Respon Aplikasi .................................................................44
1.3.1 Menjalankan sebuah Proses Background .........................................................44
2.3.1 Memberikan Parameter ke Proses Background ...............................................45
2.3.2 Mengembalikan sebuah Nilai dari sebuah Proses Background ........................45
2.3.3 Membatalkan sebuah Proses Background .......................................................46
2.3.4 Melaporkan Progres dari sebuah Proses Background dengan .........................47
2.3.5 Dispatcher untuk Mengakses Kontrol Secara Aman pada Thread Lain ............48
2.3.6 Freezable Objects .............................................................................................49
2.4 Kesimpulan ...............................................................................................................50
3 WPF Modeling Framework .............................................................................................. 51
3.1 Layout .......................................................................................................................51
3.1.1 Layout Kontrol ..................................................................................................51
3.1.2 Panel-panel Layout ...........................................................................................52
3.1.2.1 Panel Grid ......................................................................................................53
3.1.2.1.1 Grid Attached Properties ........................................................................53
3.1.2.1.2 Kontrol GridSplitter .................................................................................53
5 WPF, Just Code It!

3.1.2.2 Kontrol UniformGrid .....................................................................................54


3.1.2.3 Kontrol StackPanel ........................................................................................54
3.1.2.4 Kontrol WrapPanel ........................................................................................55
3.1.2.5 Kontrol DockPanel.........................................................................................55
3.1.2.6 Kontrol Canvas ..............................................................................................55
3.1.3 Snaplines ...........................................................................................................56
3.2 Resources .................................................................................................................56
3.2.1 Logical Resources ..............................................................................................56
3.2.2 Resources Collection .........................................................................................57
3.2.2.1 Mendeklarasikan sebuah Logical Resource ke Resources Collection ...........57
3.2.3 Application Resources.......................................................................................58
3.2.4 Static Resources dan Dynamic Resources ........................................................59
3.3 Styles.........................................................................................................................59
3.3.1 Properti dari Styles ...........................................................................................60
3.3.2 Setters ...............................................................................................................61
3.3.2.1 Property Setters ............................................................................................61
3.3.2.2 Event Setters .................................................................................................62
3.3.3 Menciptakan sebuah Style................................................................................62
3.3.3.1 Menetapkan Properti Style Secara Langsung ...............................................63
3.3.3.2 Mengatur Style didalam Resources Collection .............................................63
3.3.3.3 Menerapkan Styles ke Semua Kontrol dari Tipe Tertentu ............................64
3.3.4 Mengimplementasikan Penurunan Style..........................................................65
3.4 Kesimpulan ...............................................................................................................66
4 WPF Drawing Model ........................................................................................................67
4.1 Shapes ......................................................................................................................67
4.1.1 Rectangle dan Ellipse ........................................................................................68
4.1.2 Line ....................................................................................................................70
4.1.3 Polyline..............................................................................................................72
4.1.4 Polygon .............................................................................................................72
4.2 Transforms................................................................................................................73
4.2.1 Kelas-kelas Transforms .....................................................................................73
6 WPF, Just Code It!

4.2.2 Transformasi Shapes .........................................................................................75


4.2.3 Mentransformasi Elemen-elemen ....................................................................76
4.2.4 Flipping..............................................................................................................77
4.3 Brush .........................................................................................................................78
4.3.1 SolidColorBrush.................................................................................................80
4.3.2 LinearGradientBrush .........................................................................................82
4.3.3 RadialGradientBrush .........................................................................................84
4.3.4 ImageBrush .......................................................................................................85
4.3.5 VisualBrush .......................................................................................................87
4.4 Drawing ....................................................................................................................89
4.4.1 Menggambar sebuah Shape .............................................................................89
4.4.2 Menggambar sebuah Image .............................................................................91
4.4.3 Menggambar Text .............................................................................................92
4.4.4 Menggabungkan Drawings ...............................................................................94
4.5 Menampilkan Drawing sebagai Image .....................................................................96
4.6 Geometry..................................................................................................................99
4.6.1 Geometries vs. Shapes ....................................................................................100
4.6.2 Path .................................................................................................................100
4.6.3 Clipping ...........................................................................................................103
4.7 Kesimpulan .............................................................................................................103
5 Kontrol-kontrol WPF ......................................................................................................105
5.1 Kontrol Label ..........................................................................................................105
5.1.1 Label dan Kunci Mnemonik ............................................................................105
5.2 Kontrol Button ........................................................................................................106
5.3 Kontrol CheckBox ...................................................................................................107
5.4 Kontrol RadioButton ...............................................................................................108
5.5 Kontrol TextBlock ...................................................................................................110
5.6 Kontrol Image .........................................................................................................113
5.7 Kontrol TextBox ......................................................................................................114
5.8 Kontrol ComboBox .................................................................................................116
5.9 Konrol ListBox .........................................................................................................117
7 WPF, Just Code It!

5.10 Kontrol TreeView ....................................................................................................119


5.11 Menu ......................................................................................................................121
5.11.1 Kontrol MenuItem ..........................................................................................121
5.11.2 Kontrol ContextMenu .....................................................................................123
5.12 Toolbar....................................................................................................................124
5.13 Kesimpulan .............................................................................................................125
6 WPF Data Binding...........................................................................................................126
6.1 Data Binding ...........................................................................................................126
6.1.1 Menciptakan sebuah Binding .........................................................................127
Menetapkan Binding Source ......................................................................................129
Menetapkan Path ke Nilai ..........................................................................................129
6.1.2 Binding dan BindingExpression .......................................................................130
6.1.3 Binding ke Koleksi ...........................................................................................131
6.2 Data Template ........................................................................................................132
Pengaturan Data Template ........................................................................................133
6.3 Validasi Data ...........................................................................................................134
6.3.1 Mengasosiasikan ValidationRules dengan Binding.........................................134
6.3.2 Menyediakan Umpan Balik Visual ..................................................................136
6.4 Kesimpulan .............................................................................................................138
7 WPF Documents and Printing ........................................................................................139
7.1 Dokumen ................................................................................................................139
7.1.1 Jenis-jenis Dokumen .......................................................................................139
7.1.1.1 Fix Document ..............................................................................................139
7.1.1.2 Flow Document ...........................................................................................139
7.1.2 Kontrol-kontrol Dokumen dan Layout Teks....................................................140
7.1.2.1 Kontrol Fix Document - DocumentViewer ..................................................140
7.1.2.2 Kontrol Flow Document ..............................................................................141
FlowDocumentReader ............................................................................................141
FlowDocumentPageViewer dan FlowDocumentScrollViewer ...............................141
7.1.2.3 Teks didalam Antarmuka ............................................................................142
7.1.3 Document Packaging ......................................................................................142
8 WPF, Just Code It!

7.1.3.1 Komponen-komponen Package ..................................................................143


PackageParts ..........................................................................................................144
PackageDigitalSignatures .......................................................................................144
PackageRelationships .............................................................................................145
Dependency Relationships .....................................................................................146
Information Relationships ......................................................................................146
7.1.4 Dokumen XPS ..................................................................................................146
7.2 Pencetakan .............................................................................................................147
7.2.1 Mencetak Dokumen .......................................................................................147
7.2.2 Kelas PrintDialog .............................................................................................148
7.2.2.1 Mencetak Elemen-elemen Visual ...............................................................149
7.2.2.2 Mencetak Dokumen Alir dengan PrintDialog .............................................149
7.3 Kesimpulan .............................................................................................................150
8 WPF Multimedia ............................................................................................................151
8.1 Multimedia .............................................................................................................151
8.1.1 API Media ........................................................................................................151
8.1.2 Mode Playback Media ....................................................................................151
8.1.2.1 Mode Independent .....................................................................................152
8.1.2.2 Mode Clock .................................................................................................152
8.1.3 Kelas MediaElement .......................................................................................153
8.1.3.1 Mengontrol sebuah MediaElement ............................................................154
8.1.3.2 Menampilkan sebuah MediaElement .........................................................155
8.1.4 Kelas MediaPlayer...........................................................................................156
8.1.4.1 Mengontrol MediaPlayer ............................................................................156
8.1.4.2 Menampilkan MediaPlayer .........................................................................156
8.2 Animasi ...................................................................................................................157
8.2.1 Kelas Animation ..............................................................................................157
8.2.2 StoryBoards .....................................................................................................160
8.2.3 Repeat Behaviour ...........................................................................................162
8.2.4 Transformasi ...................................................................................................163
8.2.5 ParallelTimeLine..............................................................................................165
9 WPF, Just Code It!

8.2.6 KeyFrame ........................................................................................................167


8.3 Kesimpulan .............................................................................................................169
9 WPF Interoperability ......................................................................................................170
9.1 Interoperabilitas WPF dan Windows Form ............................................................170
9.1.1 Investasi didalam Windows Forms ke WPF ....................................................170
9.1.2 Hosting Kontrol Windows Form didalam Aplikasi WPF ..................................171
9.1.3 Hosting Kontrol WPF didalam Aplikasi Windows Form ..................................173
9.2 ClickOnce Deployment ...........................................................................................174
9.2.1 Menyebarkan dengan ClickOnce ....................................................................174
9.2.2 Menyebarkan sebuah Aplikasi Menggunakan ClickOnce ...............................175
9.2.3 Mengkonfigurasi ClickOnce Update Options ..................................................176
9.2.3.1 Mengkonfigurasi Update Settings dengan Visual Studio ............................176
9.2.3.2 Memuat Updates Secara Programatik ........................................................177
9.2.3.3 Memigrasi Settings dan User Data..............................................................179
9.2.4 Menyebarkan sebuah XBAP dengan ClickOnce ..............................................179
9.2.4.1 Pertimbangan untuk Menyebarkan didalam Lingkungan Partial-Trust ......179
9.2.4.1.1 Mengkonfigurasi Kebutuhan Keamanan Akses Kode ...........................180
9.3 Kesimpulan .............................................................................................................182

Daftar Gambar
10 WPF, Just Code It!

Gambar 1.1 UI untuk Conoso Healthcare Application.............................................................13


Gambar 1.2 WPF didalam .NET Framework 3.5 ......................................................................14
Gambar 1.3 Arsitektur WPF .....................................................................................................21
Gambar 2.1 Kotak dialog New Project .....................................................................................28
Gambar 2.2 Sebuah Windows application baru didalam Visual Studio IDE ............................29
Gambar 2.3 Pengubahan properti Window pada XAML View ................................................29
Gambar 3.1 Kontrol GridSplitter ..............................................................................................54
Gambar 4.1 Ellipse ...................................................................................................................68
Gambar 4.2 Line .......................................................................................................................72
Gambar 4.3 Ilustrasi penerapan transformasi .........................................................................76
Gambar 4.4 Contoh-contoh Brush ...........................................................................................79
Gambar 4.5 Sebuah Rectangle yang dilukis menggunakan SolidColorBrush ..........................82
Gambar 4.6 Sebuah Rectangle yang dilukis menggunakan LinearGradientBrush ..................82
Gambar 4.7 Sebuah Rectangle yang dilukis menggunakan RadialGradientBrush ..................85
Gambar 4.8 Sebuah Rectangle yang dilukis menggunakan ImageBrush.................................86
Gambar 4.9 Sebuah Rectangle yang dilukis menggunakan VisualBrush .................................87
Gambar 4.10 Sebuah GeometryDrawing .................................................................................90
Gambar 4.11 ImageDrawing 100x100 .....................................................................................92
Gambar 4.12 Drawing Gabungan ............................................................................................94
Gambar 4.13 DrawingImage ....................................................................................................96
Gambar 4.14 Clip elemen Button ..........................................................................................103
Gambar 5.1 Label dan Kunci Mnemonik ...............................................................................106
Gambar 5.2 Button dalam keadaan default, mendapatkan fokus, dan ditekan ...................107
Gambar 5.3 Kontrol CheckBox dalam berbagai keadaan ......................................................108
Gambar 5.4 RadioButton .......................................................................................................109
Gambar 5.5 Contoh penggunaan elemen TextBlock .............................................................112
Gambar 5.6 ComboBox dalam keadaan collapsed dan expanded ........................................116
Gambar 5.7 ListBox ................................................................................................................118
Gambar 5.8 Toolbar dengan Item Overflow ..........................................................................124
Gambar 6.1 Ilustrasi Data Binding .........................................................................................127
Gambar 6.2 OneWay binding ................................................................................................128
11 WPF, Just Code It!

Gambar 6.3 Mengikatkan ItemsControl ke sebuah Koleksi...................................................132


Gambar 6.4 Tampilan ErrorTemplate khusus dan ToolTip untuk sebuah error validasi .......138
Gambar 6.5 Tampilan ErrorTemplate default dan ToolTip untuk sebuah error validasi ......138
Gambar 7.1 Kotak dialog Print ...............................................................................................148
Gambar 8.1 Animasi warna pada sebuah Button ..................................................................162
Gambar 8.2 Animasi warna AutoReverse dan RepeatBehavior pada sebuah Button ..........163
Gambar 8.3 Transformasi sebuah Button .............................................................................165
Gambar 8.4 Animasi Paralel untuk sebuah Button ...............................................................167
Gambar 8.5 Animasi LinearDoubleKeyFrames untuk sebuah Button ...................................168
Gambar 9.1 Publish properties page .....................................................................................176
12 WPF, Just Code It!

Daftar Tabel

Tabel 4.1 Matriks transformasi 2-D .........................................................................................73


Tabel 4.2 Kelas Transform 2D ..................................................................................................74
Tabel 4.3 Kelas Transform Khusus ...........................................................................................75
Tabel 9.1 Fitur-fitur yang tidak aman digunakan dalam lingkungan Partial-Trust ................181
13 WPF, Just Code It!

1 Pengenalan WPF
1.1 Tentang WPF

Windows Presentation Foundation (WPF) adalah sebuah sistem presentasi generasi


berikutnya untuk membangun aplikasi-aplikasi klien Windows dengan user experiences
yang mengagumkan secara visual. Dengan WPF, Anda dapat menciptakan berbagai
aplikasi baik yang stAndalone maupun yang dihost oleh browser. Beberapa contohnya
adalah Yahoo! Messenger dan New York Times Reader, seperti halnya juga Contoso
Healthcare Sample Application yang dapat diperoleh di http://windowsclient.net yang
diperlihatkan pada gambar berikut.

Gambar 1.1 UI untuk Conoso Healthcare Application

Inti dari WPF adalah sebuah mesin render yang berbasis vektor dan tidak bergantung
pada resolusi yang dibangun untuk memanfaatkan hardware grafis modern. WPF
memperluas intinya dengan sebuah set fitur pengembangan aplikasi yang menyeluruh
yang mencakup Extensible Application Markup Language (XAML), kontrol, data binding,
layout, grafik 2-D dan 3-D, animasi, styles, templates, dokumen, media, teks, dan
tipografi. WPF tercakup didalam Microsoft .NET Framework 3.0 atau yang lebih baru,
14 WPF, Just Code It!

sehingga Anda dapat membangun aplikasi-aplikasi yang menyertakan aplikasi-aplikasi


lain dari pustaka kelas .NET Framework.

Windows Presentation Foundation (atau WPF) adalah sebuah subsistem grafis didalam
.NET Framework 3.0 (atau yang lebih baru) dan berkaitan secara langsung dengan
bahasa aplikasi XAML. WPF tercakup dalam Windows Vista dan Windows Server 2008,
dan juga tersedia untuk Windows XP Service Pack 2 atau yang lebih tinggi, dan Windows
Server 2003. WPF menyediakan sebuah model pemrograman yang konsisten untuk
membangun aplikasi dan menyediakan pemisah yang jelas antara antarmuka pengguna
dan logika bisnis. Sebuah aplikasi WPF dapat dipasang pada komputer desktop atau di-
host didalam sebuah web browser. Teknologi ini juga memungkinkan kontrol, desain,
dan pengembangan aspek-aspek visual dari program-program Windows. WPF mencoba
untuk menyatukan host layanan aplikasi: antarmuka pengguna, gambar 2D dan 3D,
dokumen-dokumen tetap dan adaptif, tipografi tingkat lanjut, diagram vektor, diagram
raster, animasi, pengikatan data, audio dan video. Walaupun WinForms akan terus
digunakan secara luas, dan Microsoft hanya menciptakan sedikit aplikasi WPF, banyak
berbagai studi kasus mempromosikan WPF untuk aplikasi-aplikasi lini bisnis.

Gambar 1.2 WPF didalam .NET Framework 3.5


15 WPF, Just Code It!

1.2 Fitur-fitur WPF

1.2.1 Antarmuka Tampilan Grafis

Semua grafis (termasuk item desktop seperti windows) adalah aplikasi Direct3D.
Direct3D bukan bermakna bahwa semua tampilannya harus berantarmuka tiga dimensi.
Pada bagian ini WPF melakukan enkapsulasi Direct3D dengan memberikan berbagai
fitur di antaraya.

 Memberikan sebuah jalan yang terpadu untuk menampilkan grafis, seperti


halnya lebih banyak fitur grafis tingkat lanjut.
 Merutekan grafis melalui Direct3D memungkinkan Windows mengalihkan
beberapa tugas grafis ke Graphics Processing Unit yang ditemukan pada kartu
grafis komputer. Hal ini dapat mereduksi beban kerja pada unit pemrosesan
Central dari komputer.
 Mendukung grafis berbasis vektor, yang memungkinkan penskalaan tanpa
mengurangi kualitas.
 Mendukung render dan interaksi model 3D dalam aplikasi-aplikasi 2D.
 Konten 2D yang interaktif dapat diletakkan diatas permukaan 3D, secara natif.

1.2.2 Interoperabilitas

WPF memberikan interoperabilitas dengan Win32: Melalui konsep hosting, seseorang


dapat menggunakan Windows Presentation Foundation didalam kode Win32 yang ada,
atau seseorang dapat menggunakan kode Win32 yang ada didalam Windows
Presentation Foundation.

Interoperabilitas dengan Windows Forms juga mungkin dilakukan melalui penggunaan


kelas ElementHost dan kelas WindowsFormsHost.
16 WPF, Just Code It!

1.2.3 Layanan Media

WPF memberikan bangun primitive untuk grafis 2D bersama dengan seperangkat kuas,
pena, geometri, dan transformasi yang built-in. Kemampuan 3D didalam WPF
merupakan sebuah subset dari seperangkat fitur lengkap yang disediakan oleh Direct3D.
Meskipun demikian, WPF memberikan integrasi yang lebih ketat dengan fitur-fitur lain
seperti user interface (UI), dokumen, dan media. Hal ini memungkinkan untuk memiliki
UI 3D, dokumen 3D, dan media 3D.

Pada WPF Terdapat dukungan untuk sebagian besar format gambar umum yang telah
distandarisasi. WPF mendukung juga format video WMV, MPEG dan beberapa berkas
AVI. Pada pendekatan ini WPF juga mendukung animasi berbasis waktu, sebagai lawan
dari pendekatan berbasis frame. Hal ini mengurangi kecepatan animasi dari bagaimana
sistem bekerja.

1.2.4 Data binding

WPF memiliki seperangkat layanan data yang built-in untuk memungkinkan


pengembang aplikasi untuk mengikatkan dan memanipulasi data didalam aplikasi.
Terdapat dukungan untuk tiga jenis data binding:

 One time: dimana klien membiarkan updates pada server.


 One way: dimana klien memiliki akses read-only ke data.
 Two way: dimana klien dapat membaca dari dan menulis data ke server.

Pengikatan data tidak memiliki penghalang pada presentasinya. WPF memberikan


template data untuk mengontrol presentasi data.

1.2.5 Antarmuka Pengguna


17 WPF, Just Code It!

Seperangkat kontrol yang built-in diberikan sebagai bagian dari WPF. Kontrol ini
memuat berbagai item-item seperti tombol, menu, dan list box. Hal yang mungkin
dinotifikasi adalah salah satu kontrol WPF yangtidak memiliki kontrol penampil data
berupa DataGrid, namun demikian vendor-vendor pihak ketiga telah menawarkan
beberapa kontrol tersebut, atau bahkan Anda dapat memperoleh kontrol tersebut
tanpa investasi.

Hal yang menarik dan diterapkan pada konsep pemograman .NET adalah diterpkannya
konsep pemisah logis antara sebuah kontrol dari penampilannya.

 Sebuah template dari kontrol dapat ditimpa untuk benar-benar mengubah


tampilan visualnya.
 Sebuah kontrol dapat memuat kontrol atau layout lainnya, yang memungkinkan
kontrol yang belum pernah dilakukan diatas komposisi.
 Fitur-fitur penyangga mode grafis, sehingga aplikasi-aplikasi tersebut tidak perlu
terganggu dengan penggambaran tampilan kembali.

1.2.6 Anotasi

Anotasi adalah kemampuan member informasi penandaan pada dokumen. Hal ini dapat
diterapkan pada basis per-obyek, untuk obyek-obyek didalam sebuah Document atau
FlowDocument. WPF hanya memberikan kemampuan untuk menciptakan, menyimpan
dan mengelola anotasi; masing-masing aplikasi harus mengekspos perancanfan
antarmuka sendiri.

1.2.7 Imaging

WPF secara natif dapat mengakses pustaka standar Windows Imaging Component (WIC)
dan API yang memungkinkan pengembang untuk menuliskan kodek gambar untuk
format berkas gambar yang telah distandarisasi.
18 WPF, Just Code It!

1.2.8 Efek

WPF dapat menghadirkan efek-efek bitmap, efek-efek ini ditampilkan dengan


mengopimalkan seluruh kemampuan hardware yang menjalankan .NET Framework 3.5
SP1 atau yang lebih baru. Fitur-fitur GPU seperti pixel shaders tidak digunakan untuk
efek-efek bitmap. Efek-efek khusus seperti dropshadows dan blurring tersedia secara
built in di teknologi frameworknya.

1.2.9 Dokumen

WPF secara natif mendukung dokumen-dokumen layaknya seperti dokumen word. WPF
menyediakan sebuah kelas yang diberi DocumentReader, yang digunakan untuk
membaca dokumen-dokumen dengan layout tetap. Kelas FlowDocumentReader
menawarkan mode-mode tampilan yang berbeda seperti per-halaman atau dapat di-
skrol dan juga menyusun kembali teks jika area tampilan diubah ukurannya.

Konsep halaman-halaman pada dokumen WPF ini mengikuti standar XML Paper
Specification, serta mendukung pembacaan dan penulisan dokumen-dokumen
berhalaman menggunakan Open Packaging Convention.

1.2.10Teks

WPF mencakup sejumlah fitur penampilan teks dan tipografi yang sebelumnya tidak
tersedia didalam GDI. Teknologi WPF ini menghadirkan antarmuka pemrograman
Windows yang pertama untuk mengekspos fitur-fitur OpenType. OpenType adalah
teknologi skalabilitas suatu ukuran font pada layar komputer.

WPF menangani teks dalam standar Unicode, dan menangani independesi teks dari sisi
pengaturan global dari sistem Windows. Pada pengelolaan teks terdapat fitur-fitur
menarik yakni.
19 WPF, Just Code It!

 mekanisme fallback yang memungkinkan arah tulisan dapat bersifat horizontal


dan vertikal.
 Mengembangkan font internasional yang bersifat komposit dari font-font yang
sudah ada.
 Informasi font komposit yang ditata rapih dalam suatu skema xml

Pengelolaan tekas pada WPF juga mendukung pemeriksaan ejaan yang built-in.
Pengelolaan teks WPF ini mendukung fitur-fitur seperti spasi otomatis, teks
internasional berbahasa inggris, pemisahan baris, penyambungan kaya, perataan
paragraf, efek-efek bitmap, tranformasi font, dan efek-efek teks ala animasi seperti
bayangan, samar (blur), glow, rotasi, dsb. Berbagai macam efek tersebut memungkinkan
pengembangan teks beranimasi yang bersifat real-time.

1.2.11Input Alternatif

WPF mendukung fungsionalitas yang terkait dengan tinta digital. Input tinta digital ini
mengadopsi dukungan teknologi Windows Ink Services Platform (WISP) yang sudah
dikenal pada implementasi tablet PC di tahun 2005 silam. Hal yang menarik dari WISP ini
adalah mengkombinasikan dan mengenkapsulasi teknologi input alternatif yang
ditanamkan saat ini pada Windows Vista

1.2.12Aksesabilitas

WPF mendukung Microsoft UI Automation yang memungkinkan para pengembang


untuk menciptakan antarmuka yang dapat diakses dengan mudah, bagi para pengguna
yang mengalami aksebilitas terbatas.
20 WPF, Just Code It!

1.3 Arsitektur WPF

Seperti halnya dengan teknologi .NET, arsitektur Windows Presentation Foundation


sebagian besar berada dalam wilayah kode terkelola, dan sedikit diantaranya
memanfaatkan komponen-komponen kode natif. Meskipun demikian, API publik yang
terekspos hanya dapat diakses melalui kode terkelola. Sementara mayoritas dari WPF
berada didalam kode terkelola, teknik penampilan aplikasi-aplikasi WPF sendiri berupa
sebuah komponen natif. Komponen ini bernama Media Integration Layer (MIL) dan
terletak didalam milcore.dll. Komponen ini berhubungan langsung dengan DirectX dan
memberikan dukungan dasar untuk permukaan 2D dan 3D, manipulasi konten
antarmuka 2D dan 3D, serta menggabungkan elemen-elemen individual dari sebuah
aplikasi WPF kedalam sebuah “cuplikan” 3D final yang merepresentasikan antarmuka
pengguna aplikasi dan merendernya ke layar. Penampilan pemutaran media dengan
Media codecs juga diimplementasikan dalam kode tidak terkelola, dan diberikan sebagai
windowscodecs.dll.

Seluruh komponen yang bersifat natif tersebut kemudian di kelola oleh sebuah
komponen natif yakni PresentationCore (presentationcore.dll). Komponen ini
memberikan sebuah wrapper terkelola untuk MIL dan mengimplementasikan layanan
inti untuk aplikasi WPF, sebuah sistem properti pengambilan nilai variable ala WPF, dan
sistem pengiriman pesan untuk implementasi servis event di antarmuka pengguna.
Komponen lain adalah komponen yang dikenal dengan PresentationFramework
(presentationframework.dll). PresentationFramework ini mengimplementasikan fitur-
fitur antarmuka pengguna akhir, termasuk layout, animasi berbasis story-board, serta
pengikatan data.
21 WPF, Just Code It!

Gambar 1.3 Arsitektur WPF

WPF mengekspos sebuah sistem properti untuk obyek-obyek yang diturunkan dari
DependencyObject. Sistem properti ini memiliki dukungan ketergantungan antar
konsumen dari property tersebut, hal ini mendukung pemicuan aksi-aksi berdasarkan
pada perubahan-perubahan didalam properties. Properties dapat berupa nilai atau
ekspesi yang dikodekan secara tegas, yang merupakan ekspresi-ekspresi khusus yang
memberikan sebuah hasil. Nilai dari properties tersebut juga dapat diturunkan dari
obyek-obyek induk. WPF properties mendukung notifikasi perubahan, yang memanggil
perilaku-perilaku bawaan kapanpun property dari elemen berubah. Perilaku khusus
dapat digunakan untuk menyebarkan notifikasi perubahan property dalam set obyek
WPF. Perilaku ini digunakan oleh sistem layout untuk memicu kalkulasi kembali dari
layout pada perubahan property, yang mengekspos sebuah gaya pemrograman
deklaratif untuk WPF, dimana hampir segalanya, dari pengaturan warna dan posisi
untuk elemen-elemen yang beranimasi dapat dicapai dengan setting properties. Hal ini
mengijinkan aplikasi-aplikasi WPF untuk ditulis dalam XAML, yang merupakan sebuah
bahasa mark-up yang deklaratif, dengan mengikatkan keyword dan atribut secara
langsung ke kelas dan property dari WPF.
22 WPF, Just Code It!

Elemen-elemen antarmuka pengguna dari sebuah aplikasi WPF dipelihara sebagai


sebuah kelas dari obyek-obyek Visual. Obyek-obyek Visual memberikan sebuah
antarmuka terkelola ke sebuah struktur komposisi yang dikelola oleh Media Integration
Layer (MIL). Masing-masing elemen dari WPF menciptakan dan menambahkan satu atau
lebih node komposisi pada pohon komposisi. Node-node komposisi berisi instruksi-
instruksi render, seperti instruksi kliping dan transformasi, bersama dengan atribut-
atribut visual lainnya.

Demikian seluruh aplikasi direpresentasikan sebagai sebuah koleksi dari node-node


komposisi, yang disimpan didalam sebuah buffer didalam memori sistem. Secara
periodik, MIL menjalankan pohon komposisi dan mengeksekusi instruksi-instruksi
render didalam masing-masing node, yang menggabungkan masing-masing elemen ke
sebuah permukaan DirectX, yang kemudian dirender pada layar.

MIL menggunakan algoritma painter, dimana semua komponen dirender dari balik layar,
yang memungkinkan efek-efek kompleks seperti transparansi agar mudah dicapai.
Proses render ini diperkuat oleh hardware menggunakan GPU. Pohon komposisi yang
tersusun oleh MIL, yang menciptakan sebuah mode grafis yang ditahan, sehingga
perubahan apapun pada pohon komposisi hanya perlu dikomunikasikan kepada MIL
secara bertahap. Hal ini juga membebaskan aplikasi untuk mengelola penggambaran
layar kembali, MIL dapat melakukannya sendiri ketika ia memiliki semua informasi yang
diperlukan.

Terkait dengan dukungan MIL Animasi dapat diimplementasikan sebagai perubahan-


perubahan yang dipicu oleh waktu pada pohon komposisi. Pada sisi yang dapat dilihat
oleh pengguna, animasi dispesifikasikan secara deklaratif, dengan menetapkan
beberapa efek animasi ke beberapa elemen melalui sebuah property dan menetapkan
durasi. Kode dasar mengupdate node-node tertentu dari pohon komposisi, melalui
obyek-obyek Visual, untuk merepresentasikan suatu keadaan pada interval waktu
tertentu maupun keadaan akhir dari suatu elemen. MIL akan merender perubahan-
perubahan pada elemen secara otomatis.
23 WPF, Just Code It!

Semua aplikasi WPF dimulai dengan dua thread:

 satu thread untuk mengelola UI


 thread latar belakang lainnya untuk menangani render dan repaint.

Render dan repaint dikelola oleh WPF sendiri, tanpa campur tangan apapun dari
pengembang. Thread UI mengembalikan Dispatcher (melalui sebuah instan dari
DispatcherObject), yang mengelola sebuah antrian dari operasi-operasi UI yang perlu
dilakukan (sebagai sebuah pohon dari obyek-obyek Visual), yang diurutkan berdasarkan
prioritas. Event-event UI, termasuk mengubah sebuah property yang mempengaruhi
layout, dan event interaksi pengguna yang dibangkitkan diantrikan didalam dispatcher,
yang memanggil handlers untuk events tersebut.

Microsoft sendiri merekomendasikan bahwa event handlers hanya mengupdate


properties untuk merefleksikan konten baru untuk kemampuan respon aplikasi; konten
yang baru dibangkitkan atau diambil didalam thread latar belakang. Thread render
mengambil sebuah salinan dari pohon visual dan menjalankan kalkulasi pohon yang
komponen-komponennya akan dapat dilihat dan merendernya ke permukaan Direct3D.
Thread render juga menyembunyikan pohon visual tersebut, sehingga hanya
perubahan-perubahan yang terjadi pada pohon yang akan dikomunikasikan, yang hanya
akan mengupdate piksel-piksel yang berubah. WPF mendukung model layout yang
ekstensibel. Layout dibagi menjadi dua fase: Mengukur dan Menyusun. Fase Mengukur
secara rekursif memanggil semua elemen dan menentukan ukuran yang akan mereka
ambil. Didalam fase Menyusun, elemen-elemen anak secara rekursif disusun oleh
induknya, yang memanggil algoritma layout dari modul layout yang sedang digunakan.

1.4 Kesimpulan

Pada tahap ini mungkin Anda sudah tidak sabar lagi untuk melakukan pengkodean, dan
ingin melepas semua teori tentang WPF sebagai latar belakang pengembangan aplikasi.
24 WPF, Just Code It!

Penulis menyadari pengetahuan pada bagian ini mungkin bersifat teoritis, tapi penulis
meyakini bahwa manfaat dari bab ini akan membantu Anda memutuskan suatu teknik
pemograman yang mengoptimalkan teknologi WPF. Bukankah mengenal suatu medan
pertempuran akan memudahkan Anda memenangkannya, dan bab inilah yang
mengenalkan medan oerang WPF pada Anda.
25 WPF, Just Code It!

2 WPF Programming Model


2.1 XAML

XAML adalah salah satu bahasa implementasi yang mengikuti permodelan keberhasilan
bahasa markup untuk pengembangan web. WPF memperkenalkan sebuah bahasa baru
yang dikenal sebagai eXtensible Application Markup Language (XAML), yang
berdasarkan pada XML. XAML dirancang sebagai sebuah metode yang lebih efisien
untuk mengembangkan antarmuka pengguna aplikasi.

Keuntungan khusus yang dibawa XAML bagi WPF adalah bahasa yang dihasilkan
menggunakan mekanisme deklaratif. Pada bahasa pemrograman yang deklaratif,
pengembang (atau perancang) mendeskripsikan perilaku dan integrasi dari komponen-
komponen tanpa penggunaan pemrograman prosedural. Hal ini memungkinkan bagi
seseorang dengan sedikit atau tanpa pengalaman pemrograman untuk membuat
seluruh aplikasi kerja tanpa pemrograman. Walaupun secara umum jarang sekali
ditemukan sebuah aplikasi yang dibangun secara menyeluruh dalam XAML, pengenalan
XAML mengijinkan perancang aplikasi untuk berkontribusi secara lebih efektif pada
siklus pengembangan aplikasi. Penggunaan XAML untuk mengembangkan antarmuka
pengguna juga mengijinkan pemisahan model dan tampilan, dan hal ini merupakan
sebuah prinsip arsitektural yang baik. Pada XAML, elemen-elemen dan atribut-atribut
dipetakan ke kelas-kelas dan property-properti dalam API dasar.

Seperti di dalam pengembangan web, baik layout maupun theme yang khusus dapat di-
markup untuk aplikasi WPF, namun XAML tidaklah dibutuhkan secara penuh. Semua
element WPF dapat dikodekan dalam bahasa .NET (C#, VB.net). Kode XAML pada
akhirnya dapat dikompilasi kedalam sebuah kode terkelola dengan cara yang sama
dengan semua bahasa .NET. Pada point ini meyakinkan bahwa penggunaan XAML untuk
pengembangan tidak menambah beban performa. XAML juga dapat dikompilasi dan
dijalankan secara "on demand" mirip dengan halaman web HTML.
26 WPF, Just Code It!

Walaupun XAML telah diperkenalkan sebagai sebuah bagian integral dari WPF, stAndard
XAML sendiri tidak menjadi khusus bagi WPF (atau bahkan .NET). XAML juga dapat
digunakan untuk mengembangkan aplikasi-aplikasi menggunakan berbagai API
pemrograman lain dan tidak bergantung pada bahasa tertentu. Meskipun demikian,
penelitian khusus telah dilakukan dalam mengembangkan API WPF untuk
memaksimalkan interoperabilitas dengan model deklaratif yang diperkenalkan oleh
XAML.

Banyak aplikasi, seperti Microsoft PowerPoint dan Word, akan mendukung ekspor
konten mereka ke XAML.

Ada beberapa subset (atau profil) dari XAML, seperti:

 XAML Presentation (XAML-P) – menyertakan semua item yang memuat WPF


v1.0.
 XML Paper Specification (XPS) – sebuah subset dari XAML-P untuk
merepresentasikan dokumen-dokumen format yang fix dan digunakan sebagai
format spool untuk subsistem pencetakan didalam Windows Vista.

Ada juga profil-profil yang spesifik untuk Workflow Foundation, dan subset-subset
khusus domain lainnya mungkin akan bermunculan dimasa mendatang.

2.2 Dasar Aplikasi WPF

Windows Presentation Foundation (WPF) merupakan generasi penerus setelah


Windows Forms untuk pengembangan aplikasi desktop. Perbedaannya dengan aplikasi
Windows Forms tradisional, aplikasi WPF memisahkan kode untuk UI dari kode untuk
fungsionalitas aplikasi. WPF adalah sebuah kemajuan yang besar dalam pengembangan
aplikasi desktop. WPF tidak hanya mengijinkan kontrol UI melalui penggunaan grafis
tingkat lanjut, namun juga memungkinkan pengembangan yang lebih cepat karena
27 WPF, Just Code It!

pemisahan kode antara presentation layer dan business logic layer mengijinkan
pengembangan yang terpisah antara desainer dan developer.

2.2.1 Jenis Aplikasi WPF

WPF mendukung tiga jenis aplikasi, yaitu Windows applications, Navigation applications,
dan XAML Browser Applications (XBAPs). Masing-masing jenis aplikasi tersebut memiliki
kelebihan dan kelemahan masing-masing.

2.2.1.1 Windows Applications

Windows applications mirip dengan aplikasi Windows Forms. Windows applications


memberikan sebuah user experience yang familiar bagi pengguna dan pengembang
Windows. Pada jenis aplikasi ini dapat dibuka banyak jendela pada satu waktu, namun
tidak terdapat sistem navigasi atau histori.

Windows application terdiri dari satu atau lebih jendela dan business logic yang terkait.
Elemen UI level teratas dari sebuah jendela adalah sebuah kelas yang diturunkan dari
kelas Window. Kelas Window diturunkan dari ContentControl, yang berarti bahwa ia
dapat memuat sebuah elemen tunggal didalam properti Content-nya. Elemen ini
biasanya merupakan sebuah kontrol layout yang dapat memuat banyak kontrol anak.

Untuk menciptakan sebuah Windows application baru, caranya adalah:

1. Didalam Visual Studio, pilih menu File > New > Project.
2. Terbuka kotak dialog New Project.
3. Didalam kotak dialog New Project, pilih WPF Application, berikan sebuah nama
(misalnya WindowsAppSample), dan klik OK.
28 WPF, Just Code It!

Gambar 2.1 Kotak dialog New Project

Sebuah aplikasi baru tercipta didalam Visual Studio integrated development


environment (IDE), seperti yang ditampilkan dalam Gambar 1.2.

Didalam Visual Studio IDE untuk aplikasi WPF, Toolbox, Properties, Designer, dan
Solution Explorer sangat mirip dengan Windows Forms designer. Yang baru disini adalah
XAML view yang terletak dibawah designer. XAML view mengijinkan Anda untuk
mengedit XAML yang mendefinisikan jendela didalam designer.
29 WPF, Just Code It!

Gambar 2.2 Sebuah Windows application baru didalam Visual Studio IDE

Penetapan nilai properti Window dapat dilakukan dengan salah satu dari dua cara
berikut ini:

1. Pada saat desain dengan memilih jendela didalam designer dan menetapkan
properti yang sesuai didalam jendela Properties.
2. Mengedit XAML untuk jendela tersebut didalam XAML view.
Contoh berikut mendemonstrasikan pengaturan properti WindowsState (dalam
kotak hijau) dengan mengaturnya didalam XAML untuk jendela:

Gambar 2.3 Pengubahan properti Window pada XAML View


30 WPF, Just Code It!

2.2.1.2 Navigation Applications

Navigation applications memberikan user experience berbasis halaman, mirip ketika


menggunakan sebuah Web site. Pada jenis aplikasi ini hanya satu halaman yang dapat
dibuka pada satu waktu, namun ia memiliki fungsionalitas jurnal yang dapat menyimpan
rekaman halaman yang dikunjungi dan mengijinkan navigasi maju mundur. Dari user
experience, jenis aplikasi ini memang seperti sebuah Web site, namun dari proses
bisnisnya jenis aplikasi ini seperti sebuah Windows application karena aplikasi ini adalah
sebuah aplikasi terkompilasi yang berjalan pada komputer desktop dan memiliki akses
penuh ke sumber daya komputer. Karena aplikasi ini adalah aplikasi desktop, maka ia
juga dapat memanfaatkan fungsionalitas lengkap dari .NET Framework tanpa batasan-
batasan keamanan.

Sebuah navigation application adalah sebuah aplikasi desktop yang menggunakan obyek
Page sebagai obyek primernya, bukan sebuah obyek Window objects. Seperti obyek
Window, obyek Page dapat memuat sebuah kontrol tunggal. Kontrol ini biasanya adalah
sebuah kontrol Grid atau beberapa kontrol berbasis layout lainnya, yang mengijinkan
penempatan banyak kontrol anak untuk pembentukan UI.

Navigation applications berbasis halaman ditempatkan (di-host) secara otomatis


didalam sebuah NavigationWindow pada saat startup. NavigationWindow memberikan
beberapa fungsionalitas built-in untuk bernavigasi, seperti tombol Back dan Forward,
serta jurnal yang melacak halaman-halaman yang telah dikunjungi baru-baru ini.

Navigation application di-host didalam sebuah jendela Navigation dan dapat dijalankan
dengan mudah dibawah full trust, sehingga aplikasi ini ideal untuk deployment didalam
lingkungan yang aman.

2.2.1.3 XBAP
31 WPF, Just Code It!

XBAP mirip dengan Navigation applications, namun aplikasi ini dirancang untuk berjalan
didalam Windows Internet Explorer. XBAP juga menggunakan obyek Page sebagai obyek
UI level teratas, dan XBAP mengijinkan model navigasi berbasis halaman seperti
penggunaan sebuah Web site. XBAP dirancang untuk berjalan didalam Internet Explorer
dan pengguna tidak perlu menyalinnya kedalam hard drive. Aplikasi ini dapat dipasang
ke sebuah server atau ke sebuah Web site dan diunduh ketika diinstansiasi.

Perbedaan utama antara XBAP dan Navigation application adalah bahwa XBAP tidak
diinstal. Karena XBAP tidak diinstal, maka ia berjalan dibawah ijin yang terbatas. Secara
umum, XBAP akan berjalan dibawah ijin yang diperbolehkan oleh zona Internet dari
Internet Explorer. Sehingga, XBAP yang berjalan dibawah kondisi stAndard tidak dapat
menggunakan file system, tidak dapat mengakses basis data, registry, dan secara umum
dilarang menggunakan sumber daya sistem yang berdampak pada resiko keamanan.
Secara teknis, XBAP dapat dijalankan dengan full trust, namun hal ini tidak
direkomendasikan karena hal tersebut memberikan akses penuh atas sumber daya
sistem Anda bagi sebuah aplikasi dari lokasi yang tidak terpercaya, sehingga
menciptakan sebuah resiko keamanan. XBAP hanya ideal untuk distribusi luas.

2.2.1.3.1 XBAP dan Halaman Web

Web browser yang mendukung XBAP adalah Internet Explorer 6.0 dan versi diatasnya.
Untuk membuka sebuah XBAP, ada 2 cara:

1. Secara langsung dari Internet Explorer.


2. Meletakkan sebuah XBAP didalam sebuah halaman Web dengan
menempelkannya didalam tag <iframe>. Hal ini mengijinkan Anda untuk
menjalankan sebuah XBAP bersama dengan konten Hypertext Markup Language
(HTML), atau untuk menjalankan XBAP didalam sebuah browser tunggal
(didalam banyak frame). Contohnya:
32 WPF, Just Code It!

2.2.1.3.2 XBAP dan Isolated Storage

Seperti yang telah disebutkan sebelumnya bahwa XBAP dilarang mengakses file system,
registry, dll. Namun XBAP diijinkan untuk mengakses isolated storage. Ukuran dari
isolated storage relatif kecil (512 kilobytes), namun ia bisa sangat berguna untuk
membaca dan menulis preferensi pengguna dan data terkait lainnya.

Untuk membaca dari dan menulis ke isolated storage, Anda dapat menggunakan kelas-
kelas StreamReader dan StreamWriter, caranya:

1. Buat sebuah instan dari kelas the IsolatedStorageFile yang merujuk ke


penyimpanan yang ingin Anda baca.

2. Buat sebuah instan dari IsolatedStorageFileStream yang merujuk ke berkas yang


ingin Anda baca atau tulis.

3. Buat sebuah StreamReader untuk membaca berkas, atau sebuah StreamWriter


untuk menulis ke berkas.
33 WPF, Just Code It!

2.2.2 Aplikasi WPF dan Keamanan

Ketika memilih sebuah jenis aplikasi WPF, pertimbangkan konteks keamanan dimana
aplikasi akan dijalankan. Dengan Windows applications dan Navigation applications yang
diinstal pada komputer desktop, Anda menjadi lebih leluasa karena keduanya dapat
berjalan dibawah full trust atau kebijakan keamanan lainnya yang telah ditentukan oleh
administrator. Sedangkan XBAP sangat dibatasi oleh batasan keamanan dari Internet
security zone. Dibawah Internet security settings stAndard, Anda tidak dapat mengakses
file system, registry, basis data lokal, menciptakan jendela stand-alone (seperti kotak
dialog), menggunakan fungsionalitas drag-and-drop Windows dan WCF Web services.

2.2.3 Mengkonfigurasi Navigasi Berbasis Halaman

Pada bagian ini kita akan mempelajari lebih dalam lagi tentang aplikasi berbasis
halaman.

2.2.3.1 Menggunakan Pages

Aplikasi berbasis halaman adalah aplikasi navigation-driven, yang mana aliran program
dikemudikan dengan navigasi pada halaman-halaman aplikasi. Aplikasi model ini tidak
cocok untuk beberapa aplikasi yang membutuhkan interaksi yang alirannya random,
namun cocok untuk aplikasi-aplikasi yang berfokus pada sebuah tugas tunggal, seperti
aplikasi kereta belanja atau wizard.

2.2.3.2 Meletakkan Pages didalam Frames

Sebuah frame adalah host untuk halaman XAML atau halaman Web dan ia meletakkan
dirinya sendiri didalam sebuah halaman atau jendela. Jadi selain selain kedalam Internet
34 WPF, Just Code It!

Explorer (untuk XBAP) dan NavigationWindow (untuk Navigation application), Anda


dapat menggunakan kontrol frame sebagai host.

Untuk meletakkan halaman kedalam sebuah frame, akses melalui properti Source dari
kontrol Frame yang mengindikasikan halaman yang dimuat kedalam frame. Contoh kode
dalam XAML:

2.2.3.3 Menggunakan Hyperlinks

Hyperlinks adalah metode yang paling umum digunakan untuk bernavigasi didalam
aplikasi berbasis halaman. Ketika hyperlink di-klik, aplikasi bernavigasi ke halaman yang
ditunjuk oleh hyperlink tersebut.

Hyperlink adalah elemen inline flow, yang berarti bahwa hyperlink harus diletakkan
didalam elemen lain yang mendukung elemen inline flow, seperti elemen TextBlock.
Ketika sebuah hyperlink diklik, sebuah instan baru dari halaman target diciptakan dan
aplikasi bernavigasi ke halaman tersebut. Hyperlink juga dapat menunjuk ke sebuah
PageFunction, namun mustahil untuk mengembalikan sebuah nilai dari PageFunction
menggunakan hyperlink.

Dengan menggunakan hyperlink, Anda dapat mengaitkan halaman-halaman yang ada


didalam aplikasi Anda, juga Anda dapat mengaitkan aplikasi Anda dengan halaman Web.
Keduanya bergantung pada nilai yang Anda berikan kedalam properti NavigateUri dari
hyperlink yang digunakan untuk menunjuk target dari hyperlink pada saat di-klik.

Berikut adalah kode untuk hyperlink dengan target halaman WPF lainnya didalam XAML:

Berikut adalah kode untuk hyperlink dengan target halaman Web didalam XAML:
35 WPF, Just Code It!

2.2.3.3.1 Menetapkan Properti NavigateUri Secara Dinamis

Agar target navigasi dari sebuah hyperlink dapat disesuaikan dengan kondisi, maka
tetapkan properti NavigateUri secara dinamis didalam kode. Berbeda dengan
penetapan target secara statis, Anda harus menetapkan properti Name dari hyperlink
didalam XAML, seperti:

Kemudian tetapkan properti NavigateUri didalam kode, seperti:

2.2.3.3.2 Navigasi Fragment

Jika halaman target dari sebuah hyperlink dapat di-scroll (di-host didalam Internet
Explorer atau menggunakan kontrol ScrollViewer), Anda dapat menggunakan navigasi
fragment untuk menspesifikasikan sebuah elemen didalam halaman target.
Spesifikasikan elemen dengan menambahkan tAnda # yang diikuti dengan nama
elemen, yaitu:

2.2.3.4 Menggunakan NavigationService

Hyperlinks menyediakan sebuah cara yang cukup mudah untuk bernavigasi antar
halaman, namun untuk model navigasi yang lebih rumit, kelas NavigationService
menyediakan kontrol yang lebih baik.
36 WPF, Just Code It!

Anda dapat memperoleh sebuah referensi ke kelas NavigationService dengan


memanggil metode statis GetNavigationService, seperti:

NavigationService memiliki sebuah metode yang disebut Navigate yang digunakan agar
aplikasi bernavigasi ke halaman target. Untuk menggunakan metode ini, ada dua cara:

1. Memberikan sebuah instan dari Uniform Resource Identifier (URI) ke metode


Navigate, seperti:

2. Menciptakan sebuah instan dari sebuah halaman baru didalam memory dan
memberikannya ke metode Navigate, seperti:

Dengan cara pertama, maka jurnal aplikasi dapat menyimpan data halaman tanpa harus
menyimpan seluruh obyek halaman didalam memory, sehingga memory overhead
menjadi lebih rendah daripada menggunakan cara kedua. Sedangkan dengan cara
kedua, Anda dapat melewatkan informasi antar halaman yang tidak dapat dilakukan
dengan cara pertama.

Fungsi lain yang disediakan oleh NavigationService adalah untuk merefresh halaman
dengan memanggil Navigation-Service.Refresh, fungsi untuk bernavigasi maju didalam
jurnal menggunakan NavigationService.GoForward dan navigasi mundur menggunakan
NavigationService.GoBack. Contoh:
37 WPF, Just Code It!

NavigationService juga memiliki dua properti boolean yang bernama CanGoBack dan
CanGoForward, yang dapat Anda gunakan untuk memeriksa apakah aplikasi dapat
bernavigasi maju atau mundur. Contoh:

Navigasi bersifat asinkron. Oleh karenanya, Anda dapat membatalkan navigasi sebelum
ia selesai dengan memanggil NavigationService.StopLoading, seperti:

Gunakan NavigationService ketika Anda ingin menggunakan jurnal, atau ingin dapat
menghentikan atau mengubah navigasi secara programatik.

2.2.4 Menggunakan Jurnal

Jurnal adalah sebuah teknologi built-in kecil didalam XBAPs dan Navigation applications
yang menyimpan daftar dari halaman-halaman yang telah dikunjungi dan mengijinkan
Anda untuk bernavigasi atas daftar ini.

2.2.4.1 Menghapus Item dari Jurnal

Menghapus item-item dari jurnal cukup mudah dilakukan. NavigationService


menyediakan sebuah metode yang disebut RemoveBackEntry, yang menghapus entri
terakhir dari jurnal dan mengembalikan sebuah instan dari JournalEntry yang
mendeskripsikan instan yang dihapus. Contoh berikut mendemonstrasikan bagaimana
cara menghapus item terakhir dari jurnal:
38 WPF, Just Code It!

Anda dapat menggunakan properti CanGoBack untuk menghapus semua item didalam
jurnal, seperti:

2.2.4.2 Menambahkan Item ke Jurnal

NavigationService menyediakan sebuah metode yang disebut AddBackEntry. Metode ini


mengambil sebuah parameter tunggal, yaitu sebuah instan dari sebuah kelas yang
diturunkan dari Custom-ContentState. Kelas ini menyimpan informasi keadaan halaman
dan menyusun kembali keadaan halaman ketika pengguna bernavigasi ke entri khusus.
Anda juga harus mengimplementasikan antarmuka IProvideCustomContentState
didalam halaman dimana Anda ingin menyediakan entri-entri jurnal khusus. Akhirnya,
Anda harus menambahkan entri jurnal khusus secara manual pada titik dimana Anda
ingin mengambil snapshot.

Berikut adalah ikhtisar prosedur tingkat tinggi yang mendeskripsikan protokol umum
untuk menambahkan entri-entri jurnal khusus.

Untuk menambahkan entri-entri jurnal khusus

1. Ciptakan sebuah kelas yang menurunkan CustomContentState. Kelas ini juga


harus ditAndai dengan atribut Serializable.
2. Tambahkan variabel-variabel anggota dan properti-properti publik ke kelas ini
yang menyimpan keadaan masing-masing kontrol pada halaman yang ingin Anda
buat.
3. Tambahkan kode untuk memberi nilai properti JournalEntryName, yang
mengindikasi nama yang akan ditampilkan didalam jurnal.
4. Beri nilai metode Replay. Metode ini dipanggil ketika aplikasi bernavigasi maju
atau mundur didalam jurnal dan digunakan untuk menyusun kembali halaman.
39 WPF, Just Code It!

Metode terbaik adalah menciptakan sebuah metode callback yang mengeksekusi


sebuah metode didalam halaman yang menerima instan kelas sebagai sebuah
parameter, sehingga mengijinkan akses halaman ke data yang disimpan.
5. Menciptakan sebuah konstruktor untuk kelas ini. Konstruktor harus menetapkan
nilai dari seluruh data keadaan halaman yang perlu disimpan. Konstruktor juga
harus mengindikasikan alamat dari metode callback untuk metode Replay dan
parameter-parameter lain yang Anda perlukan untuk instan ini (seperti
JournalEntryName).
6. Didalam halaman dimana entri jurnal khusus akan diciptakan, buatlah sebuah
metode yang menangani callback dari metode Replay. Metode ini harus
menggunakan informasi didalam parameter yang dilewatkan untuk
mengembalikan keadaan halaman.
7. Implementasikan IProvideCustomContentState didalam halaman tersebut.
Implementasi ini melibatkan implementasi metode GetContentState.
GetContentState harus mengembalikan sebuah obyek CustomContentState—
Anda mengembalikan sebuah instan dari kelas Anda didalam metode ini.
8. Tambahkan kode yang memanggil metode NavigationService.AddBackEntry pada
setiap titik dimana Anda ingin menciptakan sebuah entri jurnal khusus. Setiap
kali Anda memanggil metode ini, Anda harus menyediakan sebuah instan baru
dari kelas Anda untuk menyimpan keadaan khusus.

2.2.5 Menangani Navigation Events

Navigasi didalam aplikasi WPF terjadi secara asinkron. Oleh karenanya, metode
NavigationService.Navigate akan kembali sebelum navigasi selesai. NavigationService
mendukung beberapa event yang mengijinkan aplikasi Anda bereaksi pada titik-titik
yang berbeda didalam proses navigasi. Event-event NavigationService aktif ketika
navigasi terjadi melalui NavigationService atau melalui klik hyperlink.
40 WPF, Just Code It!

Anda dapat menangani event-event ini untuk menyediakan validasi khusus, untuk
mengupdate kemajuan navigasi, atau untuk menambahkan fungsionalitas navigasi
khusus lainnya yang dibutuhkan. Berikut adalah event-event navigasi yang didukung
oleh NavigationService.

Karena event-event NavigationService adalah event-event .NET reguler, Anda dapat


menciptakan event handlers dengan menciptakan metode-metode dengan signatur
yang benar dan kemudian menempelkannya ke event dengan operator +=, seperti:

2.2.5.1 Melewatkan Informasi ke Event-Event Navigasi

Metode NavigationService.Navigate memiliki overloads yang mengijinkan Anda untuk


melewatkan informasi tambahan yang tersedia ketika event-event navigasi sedang
ditangani.

Sebagai contoh, Anda mungkin melewatkan informasi time stamp, atau obyek yang
dapat digunakan untuk memvalidasi permintaan halaman. Untuk melewatkan informasi
tambahan ke event handlers, tinggal panggil salah satu overloads dari
NavigationService.Navigate yang mengambil sebuah parameter obyek tambahan,
seperti:

Informasi tambahan akan tersedia didalam event-event Navigated, NavigationStopped,


dan LoadCompleted melalui properti e.ExtraData, seperti:
41 WPF, Just Code It!

2.2.5.2 Membatalkan Navigasi

Anda dapat membatalkan navigasi didalam Navigating event handler dengan


menetapkan properti e.Cancel menjadi True, seperti:

2.2.6 Menggunakan Obyek-obyek PageFunction

Kelas PageFunction sangat mirip dengan kelas Page. Perbedaan yang prinsip antara
obyek-obyek Page dan obyek-obyek PageFunction adalah bahwa obyek-obyek
PageFunction dapat mengembalikan sebuah nilai. Hal ini mengijinkan Anda untuk
menciptakan halaman-halaman yang berperilaku sama dengan kotak dialog – mereka
dapat mengumpulkan informasi pengguna dan kemudian mengembalikan informasi
tersebut ke halaman utama.

Untuk menambahkan sebuah obyek PageFunction ke sebuah proyek

1. Pilih menu Project > Add New Item. Terbukalah kotak dialog Add New Item.
2. Didalam kotak dialog Add New Item, pilih PageFunction (WPF). Beri nama
PageFunction Anda dan klik Add.

Sebuah PageFunction dapat mengembalikan segala tipe obyek .NET, namun secara
default obyek tersebut bertipe String. Anda dapat mengubah tipe balikan obyek dari
PageFunction, seperti integer atau sebuah object.
42 WPF, Just Code It!

Untuk mengubah tipe balikan dari PageFunction

1. Didalam XAML view, cari baris didalam PageFunction XAML sebagai berikut:

2. Ubah parameter TypeArguments ke tipe yang Anda inginkan, misalnya menjadi


Object.

3. Didalam Code view, cari deklarasi kelas dan ubah tipenya, dari:

menjadi

Agar PageFunction Anda mengembalikan sebuah nilai, Anda harus memanggil metode
OnReturn. Metode OnReturn mengambil parameter dari tipe yang dispesifikasikan untuk
PageFunction. Anda juga dapat mengembalikan null untuk parameter ini jika tidak ada
nilai balikan yang dibutuhkan. Halaman yang dinavigasikan ke PageFunction harus
menangani event Returned untuk PageFunction tersebut. Instan dari ReturnEventArgs
yang dikembalikan oleh event tersebut memuat nilai yang dikembalikan.

Untuk mengembalikan sebuah nilai dari sebuah PageFunction

1. Didalam halaman yang bernavigasi ke PageFunction, ciptakan sebuah metode


yang menangani metode Returned dari PageFunction tersebut. Contoh:

2. Didalam halaman yang bernavigasi ke PageFunction, instansiasi PageFunction


secara programatik dan tambahkan kode untuk merelai event
PageFunction.Returned ke event handler yang baru, seperti:
43 WPF, Just Code It!

3. Didalam PageFunction, setelah tugas selesai, panggil metode OnReturn dan


lewatkan nilai balikan didalam sebuah instan baru dari ReturnEventArgs, seperti:

2.2.6.1 Menghapus Entri-entri PageFunction dari Jurnal

Karena obyek-obyek PageFunction biasanya digunakan untuk mengumpulkan masukan


pengguna, Anda mungkin tidak ingin mengijinkan pengguna untuk kembali ke sebuah
PageFunction via jurnal setelah tugas selesai.

Kelas PageFunction memiliki sebuah properti yang disebut RemoveFromJournal. Ketika


RemoveFromJournal diset menjadi True, entri-entri PageFunction dihapus secara
otomatis dari jurnal setelah pengguna selesai dengan tugas tersebut.

2.2.7 Navigasi Sederhana dan Navigasi Terstruktur

Navigasi sederhana adalah sebuah model desain umum didalam aplikasi-aplikasi ringan
berbasis halaman. Umumnya tidak ada atau hanya ada sedikit percabangan. Model ini
hanya cocok untuk beberapa jenis aplikasi, seperti wizard konfigurasi, namun jenis
aplikasi lainnya mungkin menganggap model ini kurang memadai.

Sebagai contoh adalah sebuah aplikasi kereta belanja. Seorang pengguna mungkin
menambahkan barang ke kereta belanja, kembali ke galeri untuk melihat beberapa
barang, menambahkannya ke kereta belanja, mengulangi hal ini beberapa kali lagi, dan
kemudian keluar. Navigasi sederhana tidak akan cukup untuk menangani kasus ini.

Obyek-obyek PageFunction mengijinkan Anda untuk membangun lebih banyak struktur


kedalam aplikasi Anda. Anda dapat menciptakan model-model eksekusi dengan struktur
aliran yang kompleks, dan dengan memanipulasi jurnal, Anda dapat mengontrol
bagaimana seorang pengguna dapat bernavigasi mundur didalam aplikasi.
44 WPF, Just Code It!

2.3 Mengelola Kemampuan Respon Aplikasi

Aplikasi Anda mungkin dibutuhkan untuk melakukan tugas-tugas yang mengkonsumsi


banyak waktu, seperti komputasi yang kompleks atau pengunduhan berkas. Eksekusi
tugas ini pada sebuah thread yang terpisah mengijinkan Anda untuk memelihara
kemampuan respon dari UI. Komponen BackgroundWorker adalah cara yang
direkomendasikan untuk menjalankan tugas-tugas yang mengkonsumsi waktu di
belakang layar. Ketika thread background perlu berinteraksi dengan thread UI, Anda
dapat menggunakan Dispatcher untuk mengeksekusi kode secara aman pada thread UI.

1.3.1 Menjalankan sebuah Proses Background

Metode RunWorkerAsync dari BackgroundWorker memulai eksekusi dari proses


background dengan membangkitkan event DoWork. Kode didalam DoWork event
handler dieksekusi pada sebuah thread yang terpisah.

Untuk menciptakan sebuah thread background dengan komponen BackgroundWorker

1. Didalam kode, deklarasikan sebuah instan baru dari sebuah BackgroundWorker.

2. Ciptakan sebuah metode untuk menangani event BackgroundWorker.DoWork.

3. Didalam konstruktor jendela atau halaman Anda, tambahkan kode untuk merelai
event ke handler.

4. Ditempat lain didalam kode Anda, mulailah operasi yang menghabiskan waktu
pada sebuah thread terpisah dengan memanggil metode RunWorkerAsync.
45 WPF, Just Code It!

2.3.1 Memberikan Parameter ke Proses Background

Proses background Anda mungkin membutuhkan satu atau lebih parameter, seperti
alamat dari sebuah berkas untuk diunduh. Anda dapat memberikan sebuah parameter
didalam metode RunWorkerAsync yang akan tersedia sebagai properti Argument dari
instan DoWorkEventArgs didalam DoWork event handler.

Untuk memberikan sebuah parameter ke proses background

1. Masukkan parameter didalam pemanggilan RunWorkerAsync.

2. Ambil parameter dari properti DoWorkEventArgs.Argument dan gunakan


didalam proses background.

Jika proses Anda membutuhkan lebih dari sebuah parameter tunggal, Anda mungkin
perlu membungkus banyak nilai dalam sebuah array khusus.

2.3.2 Mengembalikan sebuah Nilai dari sebuah Proses Background

Anda mungkin ingin mengembalikan sebuah nilai dari sebuah proses background. Anda
dapat melakukannya dengan mengatur properti Result dari DoWorkEventArgs didalam
DoWork event handler. Nilai ini akan tersedia didalam RunWorkerCompleted event
handler sebagai properti Result dari parameter RunWorkerCompletedEventArgs.
46 WPF, Just Code It!

2.3.3 Membatalkan sebuah Proses Background

Background-Worker mendukung pembatalan sebuah proses background, namun Anda


harus mengimplementasikan kode pembatalan tersebut secara manual. Properti
WorkerSupportsCancellation dari komponen BackgroundWorker memeriksa apakah
komponen mendukung pembatalan.

Anda dapat memanggil metode CancelAsync untuk mencoba membatalkan operasi; hal
tersebut menetapkan properti CancellationPending dari komponen BackgroundWorker
menjadi True.

Untuk membatalkan sebuah proses background

1. Didalam jendela Properties, tetapkan properti WorkerSupportsCancellation


menjadi True untuk memungkinkan komponen BackgroundWorker mendukung
pembatalan.
2. Ciptakan sebuah metode untuk membatalkan operasi background. Contoh
berikut mendemonstrasikan bagaimana cara untuk membatalkan sebuah operasi
background didalam sebuah Button.Click event handler:
47 WPF, Just Code It!

3. Didalam BackgroundWorker.DoWork event handler, lihat nilai properti


BackgroundWorker.CancellationPending. Jika nilainya True, maka
implementasikan kode untuk membatalkan operasi. Anda juga harus
menetapkan properti e.Cancel menjadi True.

2.3.4 Melaporkan Progres dari sebuah Proses Background dengan


BackgroundWorker

Anda dapat melaporkan progres dari proses background dengan memanggil metode
ReportProgress. Metode ini membangkitkan event BackgroundWorker.ProgressChanged
dan mengijinkan Anda untuk melewatkan sebuah parameter yang mengindikasikan
persentase dari progres yang telah diselesaikan ke metode yang menangani event
tersebut.
48 WPF, Just Code It!

2.3.5 Menggunakan Dispatcher untuk Mengakses Kontrol-kontrol Secara


Aman pada Thread Lain

Kadang kala, Anda mungkin ingin mengubah UI dari sebuah thread pekerja. Sebagai
contoh, Anda mungkin ingin untuk mengaktifkan atau menonaktifkan tombol-tombol
berdasarkan pada status dari thread pekerja, atau menyediakan laporan progres yang
lebih rinci daripada yang diijinkan oleh metode ReportProgess. Model thread WPF
menyediakan kelas Dispatcher untuk pemanggilan-pemanggilan lintas thread.

Dengan menggunakan Dispatcher, Anda dapat mengupdate UI Anda secara aman dari
thread-thread pekerja. Anda dapat mengambil sebuah referensi ke obyek Dispatcher
untuk sebuah elemen UI dari properti Dispatcher nya.

Dispatcher menyediakan dua metode prinsip yang akan Anda gunakan: BeginInvoke dan
Invoke. Kedua metode ini mengijinkan Anda untuk memanggil sebuah metode secara
aman pada UI thread. Metode BeginInvoke mengijinkan Anda untuk memanggil sebuah
metode secara asinkron, dan metode Invoke mengijinkan Anda untuk memanggil
49 WPF, Just Code It!

sebuah metode secara sinkron. Oleh karenanya, pemanggilan ke Dispatcher.Invoke akan


memblokir eksekusi pada thread yang dipanggil sampai metode kembali, sedangkan
pemanggilan ke Dispatcher.BeginInvoke tidak akan memblokir eksekusi.

Kedua metode baik BeginInvoke maupun Invoke mengharuskan Anda untuk


menspesifikasikan sebuah delegasi yang menunjuk ke sebuah metode untuk dieksekusi.
Anda juga dapat memberikan sebuah parameter tunggal atau sebuah array dari
parameter-parameter untuk delegasi, yang bergantung pada kebutuhan dari delegasi.
Anda juga diharuskan untuk menetapkan properti DispatcherPriority, yang menentukan
prioritas mana yang dieksekusi oleh delegasi. Sebagai tambahan, metode
Dispatcher.Invoke mengijinkan Anda untuk menetapkan sebuah periode waktu untuk
Dispatcher untuk menunggu sebelum menunda invokasi. Contoh berikut
mendemonstrasikan bagaimana cara membuat sebuah delegasi yang bernama
MyMethod menggunakan BeginInvoke dan Invoke:

2.3.6 Freezable Objects

Obyek-obyek Freezable adalah sebuah tipe khusus dari obyek yang diturunkan dari kelas
Freezable. Obyek-obyek yang sebagian besar digunakan oleh sub sistem grafis ini,
seperti kelas Brush, bisa ada dalam dua keadaan: keadaan read-write (unfrozen) dan
keadaan read-only (frozen).

Selama sebuah obyek freezable tidak dalam keadaan frozen, ia dapat diubah didalam
kode. Sebuah obyek frozen dapat diakses secara aman oleh semua thread, karena ia tak
lagi read-write, tapi read-only. Dengan obyek frozen, performa menjadi meningkat
karena ia tak lagi harus menyediakan notifikasi perubahan ke obyek-obyek lain dimana
mereka bergantung. Meskipun demikian, sekali sebuah obyek menjadi frozen, ia tidak
50 WPF, Just Code It!

bisa menjadi unfrozen. Anda dapat membekukan sebuah obyek freezable dengan
memanggil metode Freeze, seperti:

2.4 Kesimpulan

Pada bagian ini telah didiskusikan permodelan pemograman yang dimiliki WPF.Bentuk
aplikasi WPF yang beragam memungkinkan Anda, untuk membuat sebuah aplikasi yang
dapat disesuaikan dengan kondisi klien namun menggunakan permodelan pemograman
yang hampir identik. Aplikasi berjendela ala Windows, Aplikasi berorientasi jurnal,
hingga aplikasi WPF yang berjalan di atas Internet Explorer, memberikan khasanah
pilihan pengembang untuk mengembangkan aplikasi yang lebih beragam namun efisien
dari sisi investasi belajar.
51 WPF, Just Code It!

3 WPF Modeling Framework


3.1 Layout

Kontrol layout adalah kontainer yang menyediakan logika layout untuk kontrol-kontrol
yang dimuat. WPF menawarkan dukungan untuk berbagai gaya layout yang baru.
Beberapa kontrol khusus tambahan yang baru tersedia mengizinkan Anda untuk
menciptakan berbagai model layout. Bagian ini akan membahas Layout Kontrol, Panel-
panel Layout, dan Snaplines.

3.1.1 Layout Kontrol

Kontrol didalam WPF mengelola layout dan posisi mereka sendiri dan berinteraksi
dengan kontainer mereka untuk menentukan posisi akhir mereka. Bagaimana kontrol
disusun didalam sebuah panel layout bergantung pada properti layout dari kontrol yang
dimuat. Properti HorizontalAlignment dan VerticalAlignment dari kontrol-kontrol anak
menentukan bagaimana sebuah kontrol diratakan dalam arah horizontal dan vertikal,
dan properti Margin mendefinisikan area ruang yang mengelilingi kontrol. Dampak dari
properti layout kontrol dapat berbeda bergantung pada kontrol dimana mereka
diletakkan. Berikut adalah beberapa properti penting dari layout kontrol yang dapat
Anda gunakan dalam akses dan modifikasi layout kontrol dalam UI aplikasi Anda:

 FlowDirection: Mendapatkan atau menetapkan arah aliran teks atau elemen UI


lainnya didalam elemen induk yang mengontrol layout mereka.
 Height: Mendapatkan atau menetapkan tinggi dari kontrol. Jika diberi nilai Auto,
tingginya disesuaikan dengan properti layout lainnya.
 HorizontalAlignment: Mendapatkan atau menetapkan karakteristik batas
horizontal yang diterapkan ke elemen ini ketika disusun didalam sebuah elemen
induk, seperti sebuah panel atau kontrol item.
52 WPF, Just Code It!

 HorizonalContentAlignment: Mendapatkan atau menetapkan batas horizontal


dari konten milik kontrol.
 Margin: Mendapatkan atau menetapkan jarak antara masing-masing tepi kontrol
dan tepi dari kontainer atau kontrol-kontrol yang bersebelahan yang bergantung
pada kontrol layout yang menampung kontrol anak.
 MaxHeight: Mendapatkan atau menetapkan tinggi maksimum untuk sebuah
kontrol.
 MaxWidth: Mendapatkan atau menetapkan lebar maksimum untuk sebuah
kontrol.
 MinHeight: Mendapatkan atau menetapkan tinggi minimum untuk sebuah
kontrol.
 MinWidth: Mendapatkan atau menetapkan lebar minimum untuk sebuah
kontrol.
 Padding: Mendapatkan atau menetapkan besar ruang antara sebuah kontrol
dengan elemen anaknya.
 VerticalAlignment: Mendapatkan atau menetapkan karakteristik batas vertikal
yang diterapkan ke elemen ini ketika disusun didalam sebuah elemen induk,
seperti sebuah layout atau kontrol item.
 VerticalContentAlignment: Mendapatkan atau menetapkan batas vertikal
alignment dari konten milik kontrol.
 Width: Mendapatkan atau menetapkan lebar dari kontrol. Jika diberi nilai Auto,
lebar disesuaikan dengan properti layout lainnya.

3.1.2 Panel-panel Layout

WPF mencakup berbagai panel layout yang dapat digunakan untuk merancang UI Anda,
antara lain adalah Panel Grid, UniformGrid, StackPanel, WrapPanel, DockPanel dan
Canvas.
53 WPF, Just Code It!

3.1.2.1 Panel Grid

Grid adalah panel yang paling umum digunakan untuk menciptakan UI didalam WPF.
Panel Grid mengizinkan Anda untuk menciptakan layout-layout yang bergantung pada
properti Margin, HorizontalAlignment, dan VerticalAlignment dari kontrol-kontrol anak
yang dimuatnya. Kontrol-kontrol yang diletakkan didalam sebuah kontrol Grid
digambarkan sesuai urutan mereka didalam markup atau kode, sehingga Anda dapat
menciptakan UI yang berlapis. Kontrol Grid mengizinkan Anda untuk mendefinisikan
baris dan kolom didalam grid. Kemudian Anda dapat menambahkan kontrol-kontrol
anak untuk menciptakan sebuah layout yang lebih terstruktur.

3.1.2.1.1 Grid Attached Properties

Attached properties adalah properti-properti dari sebuah elemen penampung, seperti


sebuah kontrol layout, yang menempel ke sebuah elemen yang ditampung. Properti
ditetapkan oleh elemen yang ditampung, namun biasanya mempengaruhi bagaimana
elemen tersebut dirender atau diletakkan didalam elemen penampung. Seperti didalam
kontrol Grid yang memberikan properti-properti yang tertempel pada kontrol-kontrol
anaknya.

3.1.2.1.2 Kontrol GridSplitter

Kontrol GridSplitter mengizinkan pengguna untuk mengubah ukuran baris atau kolom
grid pada saat dijalankan. Kontrol GridSplitter tampil sebagai sebuah bar vertikal atau
horizontal antara dua baris atau kolom yang dapat dipindahkan oleh pengguna untuk
menyesuaikan ukuran baris atau kolom diantaranya. Kontrol ini mudah digunakan oleh
pengguna, hanya dengan drag and drop kontrol dari Toolbox, namun pengguna harus
melakukan sejumlah konfigurasi agar grid splitter dapat bekerja dengan benar.
54 WPF, Just Code It!

Gambar 3.1 Kontrol GridSplitter

3.1.2.2 Kontrol UniformGrid

Kontrol UniformGrid secara otomatis meletakkan kontrol-kontrol didalam grid dengan


ukuran yang seragam, serta menyesuaikan ukuran dan jumlah baris dan kolom seiring
dengan penambahan jumlah kontrol didala grid yang bersangkutan. Kontrol ini biasanya
tidak digunakan untuk merancang UI keseluruhan, namun ia sangat berguna untuk
menciptakan layout yang membutuhkan grid berukuran seragam, seperti papan catur
atau tombol-tombol pada kalkulator.

3.1.2.3 Kontrol StackPanel

Kontrol StackPanel menyediakan sebuah model layout yang sederhana. Kontrol ini
menumpuk kontrol-kontrol yang dimuatnya sesuai urutan definisi mereka. Biasanya,
kontainer StackPanel menumpuk kontrol-kontrol secara vertikal. Anda juga dapat
menciptakan sebuah stack horizontal dengan menetapkan properti Orientation dengan
nilai Horizontal.
55 WPF, Just Code It!

3.1.2.4 Kontrol WrapPanel

Kontrol WrapPanel meletakkan kontrol-kontrol didalam sebuah baris horizontal secara


bersebelahan hingga ruang horizontal yang tersedia didalam WrapPanel terisi penuh.
Kemudian ia menciptakan baris tambahan hingga semua kontrol yang dimuatnya
mendapat tempat. Penggunaan umum untuk panel layout ini adalah untuk
menyediakan layout otomatis untuk set kontrol terkait yang mungkin sering diresize,
seperti didalam sebuah toolbar.

3.1.2.5 Kontrol DockPanel

Kontrol DockPanel menyediakan sebuah kontainer yang mengizinkan Anda untuk


merapatkan kontrol-kontrol yang dimuat ke tepi DockPanel. Dalam pengembangan
Windows Forms, pemampatan dilakukan melalui properti Dock pada masing-masing
kontrol individual. Dock biasanya berguna untuk menempelkan kontrol-kontrol seperti
toolbar atau menu ke tepi UI. Posisi dari kontrol-kontrol yang di-dok tetap konstan tak
peduli bagaimana pengguna mengubah ukuran UI.

3.1.2.6 Kontrol Canvas

Kontrol Canvas adalah sebuah kontainer yang mengizinkan pengaturan posisi yang
absolut dari kontrol-kontrol yang dimuatnya. Kontrol ini tidak memiliki logika layout dari
dirinya sendiri, dan semua kontrol yang dimuat diletakkan dengan dasar empat properti
yang tertempel: Canvas.Top, Canvas.Bottom, Canvas.Right, dan Canvas.Left. Nilai dari
masing-masing properti ini menunjukkan jarak antara tepi yang ditunjuk dari kontrol
Canvas dan tepi yang bersesuaian dari kontrol anak. Anda hanya dapat mendefinisikan
satu properti horizontal dan satu properti vertikal untuk masing-masing kontrol yang
dimuat. Oleh karena itu, Anda tidak dapat menetapkan nilai Canvas.Left dan
Canvas.Right untuk sebuah kontrol tunggal, tidak juga Canvas.Top dan Canvas.Bottom.
56 WPF, Just Code It!

Ketika kontainer Canvas diubah ukurannya, kontrol-kontrol yang dimuat


mempertahankan jarak tetapnya dari tepi Canvas.

3.1.3 Snaplines

Snaplines adalah alat peraga visual didalam Visual Studio Integrated Development
Environment (IDE) yang menyediakan umpan balik kepada pengembang ketika tepi
kontrol diratakan atau ketika konten kontrol diratakan. Anda dapat menggunakan
snaplines untuk meratakan kontrol dan konten didalam UI pada waktu perancangan.
Ketika Anda meletakkan kontrol secara manual dengan mouse didalam Designer,
snaplines muncul ketika tepi horizontal atau vertical dari kontrol ada dalam alignment.
Snaplines juga menunjukkan apakah konten diratakan, yang mengizinkan Anda untuk
meratakan konten dalam banyak kontrol.

3.2 Resources

Resources mengizinkan Anda untuk mendefinisikan obyek-obyek untuk digunakan


dalam aplikasi Anda dan mengizinkan Anda untuk berbagi obyek-obyek diantara
elemen-elemen.

3.2.1 Logical Resources

Logical resources adalah obyek-obyek yang didefinisikan didalam XAML dan dapat
digunakan oleh elemen-elemen yang ada didalam aplikasi Anda. Elemen-elemen
didalam UI Anda dapat mengakses resource kapanpun dibutuhkan. Ada dua keuntungan
yang ditawarkan:

1. Reusabilitas.
57 WPF, Just Code It!

Anda mendefinisikan obyek-obyek tersebut hanya sekali, dan dapat


dipergunakan berulang kali oleh elemen-elemen lain kapanpun.
2. Fleksibilitas.
Dengan pemisahan obyek-obyek yang digunakan oleh UI Anda dari UI sendiri,
Anda dapat melakukan refactor bagian-bagian dari UI tanpa harus merancang
ulang secara keseluruhan.

3.2.2 Resources Collection

Anda dapat mendefinisikan sebuah resource didalam beberapa lokasi—didalam


Resources collection for the Element, di dalam Resources collection for the Window,
didalam Resources collection for the Application, atau didalam sebuah resource
dictionary. Setiap elemen WPF mendefinisikan sebuah Resources collection, yang dapat
digunakan untuk mendefinisikan obyek-obyek yang tersedia bagi elemen tersebut dan
elemen-elemen didalam pohon visualnya. Walaupun pada umumnya resources
didefinisikan didalam Resources collection dari Window, Anda dapat mendefinisikan
sebuah resource didalam Resources collection elemen manapun dan mengaksesnya
asalkan elemen pengakses adalah bagian dari pohon visual elemen.

3.2.2.1 Mendeklarasikan sebuah Logical Resource ke Resources Collection

Anda mendeklarasikan sebuah logical resource dengan menambahkannya ke sebuah


Resources collection.

<Window.Resources>
<RadialGradientBrush x:Key="myBrush">
<GradientStop Color="CornflowerBlue" Offset="0" />
<GradientStop Color="Crimson" Offset="1" />
</RadialGradientBrush>
</Window.Resources>
58 WPF, Just Code It!

Jika Anda tidak menginginkan sebuah resource tersedia bagi seluruh Window, Anda
dapat mendefinisikannya didalam Resources collection dari sebuah elemen didalam
Window.

<Grid>
<Grid.Resources>
<RadialGradientBrush x:Key="myBrush">
<GradientStop Color="CornflowerBlue" Offset="0" />
<GradientStop Color="Crimson" Offset="1" />
</RadialGradientBrush>
</Grid.Resources>
</Grid>

Kegunaannya terbatas, dan skenario paling umum adalah mendefinisikan resources


didalam koleksi Window.Resources. Satu hal yang perlu diingat adalah bahwa saat
menggunakan resource statis, Anda harus mendefinisikan resource didalam kode XAML
sebelum Anda merujuknya.
Setiap obyek yang dideklarasikan sebagai sebuah Resource harus menetapkan properti
x:Key. Ini adalah nama yang akan digunakan oleh elemen-elemen WPF lain untuk
mengakses resource. Ada satu pengecualian untuk aturan ini: Obyek-obyek Style yang
menetapkan properti TargetType tidak perlu menetapkan properti x:Key secara eksplisit
karena ia ditetapkan secara implisit dibalik layar.

Properti x:Key tidak harus unik dalam aplikasi, namun ia harus unik didalam Resources
collection dimana ia didefinisikan. Karenanya, Anda dapat mendefinisikan satu resource
didalam koleksi Grid.Resources dengan key myBrush dan resource lainnya didalam
koleksi Window.Resources dengan key yang sama.

3.2.3 Application Resources

Untuk mendefinisikan resources pada level elemen atau Window, Anda dapat
mendefinisikan resources yang dapat diakses oleh semua obyek didalam aplikasi
59 WPF, Just Code It!

tertentu. Anda dapat menciptakan sebuah application resource dengan membuka


berkas App.xaml dan menambahkan resource kedalam koleksi Application.Resources.

<Application x:Class="WpfApplication2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<SolidColorBrush x:Key="appBrush" Color="PapayaWhip" />
</Application.Resources>
</Application>

3.2.4 Static Resources dan Dynamic Resources

Perbedaan antara DynamicResource dan StaticResource terletak pada bagaimana


resources diambil oleh elemen-elemen pengacu. Resources yang diacu oleh
StaticResource diambil sekali oleh elemen pengacu dan digunakan selama resource
masih ada. Resources yang diacu dengan DynamicResource, diambil setiap kali obyek
yang diacu digunakan.

Kekurangan dari penggunaan dynamic resources adalah bahwa mereka cenderung


menurunkan performa aplikasi. Karena resources diambil setiap kali mereka digunakan,
dynamic resources dapat mereduksi efisiensi dari sebuah aplikasi. Teknik terbaik adalah
menggunakan static resources kecuali ada alasan khusus untuk menggunakan dynamic
resource.

3.3 Styles

Styles mengizinkan Anda untuk mendefinisikan gaya visual yang konsisten untuk aplikasi
Anda. Styles dapat dianalogikan dengan cascading style sheets (css) seperti yang
digunakan didalam halaman Hypertext Markup Language (HTML). Pada dasarnya Styles
60 WPF, Just Code It!

memberi tahu presentation layer untuk menggantikan sebuah tampilan visual yang baru
untuk tampilan visual yang standar.

Sytes dapat Anda gunakan untuk:

 Mendefinisikan sebuah skema warna dan ukuran standar untuk aplikasi Anda.
 Mengubah UI secara keseluruhan dengan mudah.
 Memberikan look and feel yang konsisten untuk aplikasi Anda dalam berbagai
situasi.
 Menetapkan properties dan merelai event-event pada elemen-elemen UI
melalui aplikasi dari style-style tersebut.
 Menciptakan elemen-elemen visual yang secara dinamis merespon perubahan-
perubahan properti melalui aplikasi triggers, yang mendengarkan perubahan
properti dan kemudian menerapkan perubahan style sebagai responnya.

3.3.1 Properti dari Styles

Kelas Style memuat informasi tentang penetapan style sekelompok properti. Sebuah
Style dapat diciptakan untuk diterapkan ke sebuah instan tunggal dari sebuah elemen,
ke semua instan dari sebuah tipe elemen, atau lintas tipe elemen.

 BasedOn: Menunjuk style lain dimana style ini mengacu. Properti ini sangat
berguna untuk menciptakan style-style yang diturunkan.
 Resources: Memuat sekumpulan sumber daya lokal yang digunakan oleh style.
 Setters: Memuat sekumpulan obyek-obyek Setter atau EventSetter. Obyek-obyek
ini digunakan untuk menetapkan properti atau event pada sebuah elemen
sebagai bagaian dari sebuah style.
 TargetType: Menunjukkan tipe elemen yang dituju untuk style.
 Triggers: Memuat sekumpulan obyek-obyek Trigger dan obyek-obyek terkait
yang mengizinkan Anda untuk mempersiapkan perubahan dalam UI sebagai
respon untuk perubahan-perubahan didalam properties.
61 WPF, Just Code It!

3.3.2 Setters

Styles menggunakan sekumpulan Setters untuk menerapkan perubahan-perubahan


style. Tipe Ada dua jenis Setters yaitu property setters (atau hanya Setters) dan event
setters. Setter yang paling umum digunakan adalah property setter, yang mengizinkan
Anda untuk menetapkan sebuah properti. Sedangkan Event setters mengizinkan Anda
untuk merelai event handlers sebagai bagian dari sebuah style yang diterapkan.

3.3.2.1 Property Setters

Property setters, yang direpresentasikan oleh tag <Setter> didalam XAML, mengizinkan
Anda untuk menetapkan properties dari elemen-elemen dengan nilai tertentu. Dua
properti penting dari sebuah Property Setter:

1. Properti Property: mempersiapkan properti yang ditetapkan oleh Setter.


2. Properti Value: menunjukkan nilai yang ditetapkan pada properti.

Contoh berikut mendemonstrasikan sebuah Setter yang menetapkan properti


Background dari sebuah elemen Button menjadi Red:

<Setter Property="Button.Background" Value="Red" />

Nilai untuk properti Property harus berformat sbb:

Element.PropertyName

Jika Anda ingin menciptakan sebuah style yang menetapkan sebuah properti pada
banyak tipe elemen yang berbeda, Anda dapat menetapkan style pada sebuah kelas
umum yang menurunkan elemen-elemen.

<Style>
<Setter Property="Control.Background" Value="Red" />
</Style>
62 WPF, Just Code It!

Style ini menetapkan properti Background dari semua elemen yang diturunkan dari
Control yang diterapkan.

3.3.2.2 Event Setters

Event setters (direpresentasikan oleh tag <EventSetter>) mirip dengan property setters,
namun mereka menetapkan event handlers. Dua properti penting dari sebuah
EventSetter:

1. Properti Event: menspesifikasikan event dimana handler ditetapkan.


2. properti Handler: menspesifikasikan event handler untuk ditempelkan ke event.

Contoh:

<EventSetter Event="Button.MouseEnter" Handler="Button_MouseEnter" />

Nilai dari properti Handler harus menspesifikasikan sebuah event handler yang masih
ada dengan signature yang tepat untuk tipe event dimana ia terhubung. Mirip dengan
property setters, format untuk properti Event adalah:

Element.EventName

Dimana tipe element dispesifikasikan, yang diikuti oleh nama event.

3.3.3 Menciptakan sebuah Style

Anda telah melihat implementasi yang paling sederhana dari sebuah style: sebuah
Setter tunggal diantara dua tag Style, namun Anda belum melihat bagaimana cara
menerapkan sebuah style ke sebuah element. Ada beberapa cara untuk menerapkan
sebuah style ke sebuah elemen atau ke elemen-elemen.
63 WPF, Just Code It!

3.3.3.1 Menetapkan Properti Style Secara Langsung

Cara paling langsung untuk menerapkan sebuah style ke sebuah element adalah
pengaturan properti Style secara langsung didalam XAML. Contoh berikut
mendemonstrasikan pengaturan secara langsung properti Style dari sebuah elemen
Button:

<Button Height="25" Name="Button1" Width="100">


<Button.Style>
<Style>
<Setter Property="Button.Content" Value="Style set directly" />
<Setter Property="Button.Background" Value="Red" />
</Style>
</Button.Style>
</Button>

3.3.3.2 Mengatur Style didalam Resources Collection

Metode paling umum untuk pengaturan style adalah menciptakan style sebagai anggota
dari Resources collection dan kemudian menerapkan style tersebut ke element-elemen
didalam UI Anda dengan memilih resource. Contoh berikut mendemonstrasikan
penciptaan style sebagai bagian dari Windows.Resources collection:

<Window.Resources>
<Style x:Key="StyleOne">
<Setter Property="Button.Content" Value="Style defined in
resources" />
<Setter Property="Button.Background" Value="Red" />
</Style>
</Window.Resources>

Anda harus memberikan nilai key untuk Style yang Anda definisikan didalam Resources
collection. Kemudian Anda dapat menerapkan style tersebut ke sebuah elemen dengan
memilih resource, seperti:
64 WPF, Just Code It!

<Button Name="Button1" Style="{StaticResource StyleOne}" Height="30"


Width="200" />

Keuntungan mendefinisikan Style didalam bagian Resources adalah bahwa Anda dapat
menerapkan Style tersebut ke banyak elemen hanya dengan memilih resource.

3.3.3.3 Menerapkan Styles ke Semua Kontrol dari Tipe Tertentu

Anda dapat menerapkan sebuah style ke semua objek dari sebuah kontrol dengan
menetapkan properti TargetType ke tipe yang sesuai. Ketika Anda menetapkan properti
TargetType pada sebuah Style, Style tersebut diterapkan ke semua elemen dari tipe
tersebut secara otomatis. Anda tidak perlu menspesifikasikan nama tipe yang
memenuhi kualifikasi didalam properti Property dari Setters apapun yang Anda
gunakan—Anda dapat langsung merujuk ke nama properti. Ketika Anda
menspesifikasikan TargetType untuk sebuah Style yang telah Anda definisikan didalam
sebuah Resources collection, Anda tidak perlu memberikan sebuah nilai key untuk style
tersebut. Contoh berikut mendemonstrasikan penggunaan properti TargetType:

<Window.Resources>
<Style TargetType="Button">
<Setter Property=" Content" Value="Style set for all buttons" />
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>

Ketika Anda menerapkan properti TargetType, Anda tidak perlu menambahkan markup
tambahan apapun ke elemen-elemen bertipe tersebut untuk menerapkan style.

Jika Anda ingin elemen individu dikeluarkan dari style, Anda dapat menetapkan style
pada elemen tersebut secara eksplisit, seperti:

<Button Style="{x:Null}" Margin="10">No Style</Button>


65 WPF, Just Code It!

Contoh ini secara eksplisit menetapkan Style dengan Null, yang menyebabkan Button
kembali ke tampilan default. Anda juga dapat menetapkan Style ke Style lain secara
langsung.

3.3.4 Mengimplementasikan Penurunan Style

Anda dapat menggunakan penurunan untuk menciptakan style yang sesuai dengan
“look and feel” dasar dari style original namun menyediakan perbedaan-perbedaan
yang mengganti beberapa kontrol dari yang kontrol yang lain. Sebagai contoh, Anda
mungkin menciptakan satu Style untuk semua elemen Button didalam UI Anda dan
menciptakan sebuah style yang diturunkan untuk menyediakan penekanan untuk salah
satu tombol. Anda dapat menggunakan properti BasedOn untuk menciptakan obyek-
obyek Style yang diturunkan dari obyek-obyek Style lainnya. Properti BasedOn mengacu
style lain dan secara otomatis menurunkan semua anggota dari Style tersebut dan
kemudian mengizinkan Anda untuk membangun Style tersebut dengan menambahkan
anggota-anggota tambahan.

Contoh berikut mendemonstrasikan dua obyek Style—sebuah Style asli dan sebuah Style
yang diturunkan:

<Window.Resources>
<Style x:Key="StyleOne">
<Setter Property="Button.Content" Value="Style set in original
Style" />
<Setter Property="Button.Background" Value="Red" />
<Setter Property="Button.FontSize" Value="15" />
<Setter Property="Button.FontFamily" Value="Arial" />
</Style>

<Style x:Key="StyleTwo" BasedOn="{StaticResource StyleOne}">


<Setter Property="Button.Content" Value="Style set by inherited
style" />
<Setter Property="Button.Background" Value="AliceBlue" />
66 WPF, Just Code It!

<Setter Property="Button.FontStyle" Value="Italic" />


</Style>
</Window.Resources>

Ketika sebuah properti ditetapkan dalam style original maupun style yang diturunkan,
nilai properti yang ditetapkan oleh style yang diturunkan selalu memiliki hak yang lebih
tinggi. Namun ketika sebuah properti ditetapkan oleh style original dan tidak ditetapkan
oleh style yang diturunkan, pengaturan properti original dipertahankan.

3.4 Kesimpulan

Pada bagian ini Kita telah membicarakan framework permodelan dan perancangan
antarmuka WPF. Perancangan dan permodelan WPF dapat dilakukan dengan mengatur
tata letak yang beragam, dukungan pengaksesan sumber daya antarmuka yang berbasis
XAML, dan juga dukungan langsung akses desain theme yang dimiliki oleh WPF.
Berbagai permodelan dasar antarmuka tersebut diharapkan dapat menjadi salah satu
kapabilitas bagi pengembang untuk membuat sebuah aplikasi yang menarik bagi
pengguna.
67 WPF, Just Code It!

4 WPF Drawing Model

Pada bab ini, Anda belajar menciptakan berbagai macam bentuk (shape) yang
sederhana maupun yang kompleks (geometri), melakukan transformasi atas bentuk-
bentuk tersebut, serta menggunakan berbagai macam kuas (brush) yang berbeda untuk
menciptakan efek-efek tertentu.

4.1 Shapes

Shape adalah sebuah tipe dari UIElement yang mengijinkan pembuatan gambar
berbagai bangun ke layar antarmuka. Karena shape adalah elemen-elemen antarmuka,
Obyek-obyek Shape dapat digunakan didalam elemen-elemen Panel dan sebagian besar
kontrol lainnya.

WPF menyediakan sejumlah obyek-obyek Shape yang siap digunakan. Semua obyek
shape diturunkan dari kelas Shape. Obyek-obyek shape yang tersedia mencakup Ellipse,
Line, Path, Polygon, Polyline dan Rectangle. Obyek-obyek Shape memiliki properti sbb:

 Fill: Obyek Brush yang melukis interior dari shape.


 Stroke: Obyek Brush yang melukis tepi dari shape.
 StrokeThickness: Menetapkan ketebalan border dalam unit-unit yang device-
independent.
 Stretch: Menentukan bagaimana sebuah shape akan diregangkan untuk mengisi
ruang yang tersedia.

Nilai-nilai yang mungkin untuk properti Stretch:

 None: Shape digambarkan dengan ukuran penuh.


 Uniform: Shape diregangkan untuk mengisi dimensi ruang yang tersedia, namun
aspek rasio dari shape dipertahankan.
68 WPF, Just Code It!

 Fill: Shape diregangkan dalam kedua dimensi untuk mengisi ruang yang tersedia,
namun aspek rasio dari shape tidak dipertahankan.
 UniformToFill: Shape diperbesar untuk mengisi seluruh ruang gambar yang
tersedia dengan aspek rasio dipertahankan. Pemotongan shape mungkin
dilakukan agar pas dengan ruang.

4.1.1 Rectangle dan Ellipse

Kelas Rectangle merepresentasikan gambar sebuah persegi panjang, sedangkan kelas


Ellipse merepresentasikan gambar sebuah elips. Gambaran visualnya ditentukan oleh
properti Height dan Width. Untuk menggambar sebuah lingkaran, nilai Width dan
Height harus sama. Contoh berikut merepresentasikan sebuah persegi dan sebuah elips
yang memiliki tinggi 100 unit dan lebar 200 unit:

<Rectangle Height="100" Width="200" Fill="Red"/>

<Ellipse Height="100" Width="200" Fill="Red"/>

Jika properti Height dan Width tidak ditetapkan secara eksplisit, Anda dapat
menggunakan properti Stretch untuk mendefinisikan bagaimana persegi tersebut
mengisi ruang yang tersedia.

Gambar 4.1 Ellipse

<Ellipse
Fill="Yellow"
Height="100"
Width="200"
69 WPF, Just Code It!

StrokeThickness="2"
Stroke="Black"/>

C#
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace SDKSample
{
public partial class SetBackgroundColorOfShapeExample : Page
{
public SetBackgroundColorOfShapeExample()
{
// Create a StackPanel to contain the shape.
StackPanel myStackPanel = new StackPanel();

// Create a red Ellipse.


Ellipse myEllipse = new Ellipse();

// Create a SolidColorBrush with a red color to fill the


// Ellipse with.
SolidColorBrush mySolidColorBrush = new SolidColorBrush();

// Describes the brush's color using RGB values.


// Each value has a range of 0-255.
mySolidColorBrush.Color = Color.FromArgb(255, 255, 255, 0);
myEllipse.Fill = mySolidColorBrush;
myEllipse.StrokeThickness = 2;
myEllipse.Stroke = Brushes.Black;

// Set the width and height of the Ellipse.


myEllipse.Width = 200;
myEllipse.Height = 100;
70 WPF, Just Code It!

// Add the Ellipse to the StackPanel.


myStackPanel.Children.Add(myEllipse);
this.Content = myStackPanel;
}
}
}

4.1.2 Line

Kelas Line merepresentasikan sebuah garis yang menghubungkan dua titik koordinat.
Sistem koordinat yang digunakan untuk menggambar obyek-obyek Line berpusat pada
pojok kiri atas dari apapun yang memuat garis tersebut. Sebagai contoh, jika garis
berada didalam sebuah sel grid, maka titik (0,0) direpresentasikan oleh titik pojok kiri
atas dari sel grid. Anda dapat menciptakan sebuah obyek Line dengan menetapkan
properti X1, Y1, X2, dan Y2, seperti:

<Line Stroke="Red" X1="0" Y1="50" X2="100" Y2="440"/>

Contoh berikut memperlihatkan beberapa cara untuk menggambarkan koordinat-


koordinat garis dan properti stroke:

<Canvas Height="300" Width="300">


<!-- menggambar garis diagonal dari (10,10) ke (50,50). -->
<Line
X1="10" Y1="10"
X2="50" Y2="50"
Stroke="Black"
StrokeThickness="4" />

<!—menggambar diagonal kemudian menggesernya ke kanan 100 pixel -->


<Line
X1="10" Y1="10"
X2="50" Y2="50"
StrokeThickness="4"
Canvas.Left="100">
71 WPF, Just Code It!

<Line.Stroke>
<RadialGradientBrush GradientOrigin="0.5,0.5" Center="0.5,0.5"
RadiusX="0.5" RadiusY="0.5">
<RadialGradientBrush.GradientStops>
<GradientStop Color="Red" Offset="0" />
<GradientStop Color="Blue" Offset="0.25" />
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
</Line.Stroke>
</Line>

<!-- menggambar garis horizontal (10,60) ke (150,60). -->


<Line
X1="10" Y1="60"
X2="150" Y2="60"
Stroke="Black"
StrokeThickness="4"/>
</Canvas>

C#
//
// Add a Line Element
//
myLine = new Line();
myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;

myLine.X1 = 1;
myLine.X2 = 50;
myLine.Y1 = 1;
myLine.Y2 = 50;

myLine.HorizontalAlignment = HorizontalAlignment.Left;
myLine.VerticalAlignment = VerticalAlignment.Center;
myLine.StrokeThickness = 2;
myGrid.Children.Add(myLine);
72 WPF, Just Code It!

Gambar 4.2 Line

Walaupun kelas Line menyediakan properti Fill, menetapkan properti ini tidak berefek
karena sebuah Line tidak memiliki area yang bisa diisi.

4.1.3 Polyline

Kelas Polyline adalah sebuah shape yang lebih kompleks daripada Line. Pada dasarnya
Polyline adalah satu set titik-titik yang berkumpul. Kelas Polyline mengekspos sebuah
koleksi Points yang menggambarkan titik-titik didalam shape ini. Shape dimulai pada
titik pertama didalam koleksi, kemudian menghubungkan garis-garis lurus antara titik-
titik berikutnya didalam koleksi, dan selesai pada titik terakhir didalam koleksi. Contoh
berikut menggambarkan sebuah Polyline dengan shape gigi gergaji:

<Polyline Stroke="Blue" Points="300, 300 400, 400 400, 300 500, 400
500, 300"/>

4.1.4 Polygon

Kelas Polygon sangat mirip dengan kelas Polyline. Kelas ini juga mengekspos sebuah
koleksi Points yang menggambarkan titik-titik dari shape dan menghubungkan titik-titik
tersebut. Perbedaan utamanya adalah Polygon juga menghubungkan titik pertama
dengan titik terakhir dan melukis interior dari shape dengan Brush yang didefinisikan
didalam properti Fill.

Contoh berikut mendemonstrasikan sebuah Polygon yang mirip dengan contoh Polyline
sebelumnya:
73 WPF, Just Code It!

<Polygon Fill="Blue" Points="300, 300 400, 400 400, 300 500, 400 500,
300"/>

4.2 Transforms

Transformations (disebut juga sebagai transforms) menggambarkan bagaimana cara


untuk memetakan atau mentransformasikan titik-titik dari satu ruang koordinat ke
ruang koordinat lainnya. Pemetaan ini dijelaskan oleh matriks transformasi yang terdiri
dari 3 baris dan 3 kolom nilai-nilai double.

Tabel berikut menampilkan struktur dari sebuah matriks WPF.

Tabel 4.1 Matriks transformasi 2-D


M11 M12 0.0
Default: 1.0 Default: 0.0
M21 M22 0.0
Default: 0.0 Default: 1.0
OffsetX OffsetY 1.0
Default: 0.0 Default: 0.0

Dengan memanipulasi nilai-nilai matriks, Anda dapat merotasi, menskala, memiringkan,


dan menggeser (translate) sebuah obyek. Sebagai contoh, jika Anda mengubah nilai
didalam kolom pertama baris ketiga (nilai OffsetX) menjadi 100, Anda dapat
menggunakannya untuk memindahkan sebuah obyek 100 unit sepanjang sumbu x. Jika
Anda mengubah nilai didalam kolom kedua baris kedua menjadi 3, Anda dapat
menggunakannya untuk meregangkan sebuah obyek menjadi tiga kali dari tinggi
semula. Jika Anda mengubah kedua nilai tersebut, Anda memindahkan obyek 100 unit
sepanjang sumbu x dan meregangkan tingginya sebesar 3 kali.

4.2.1 Kelas-kelas Transforms


74 WPF, Just Code It!

WPF menyediakan kelas-kelas Transform 2-D untuk operasi-operasi transformasi umum:

Tabel 4.2 Kelas Transform 2D

Kelas Deskripsi Ilustrasi


RotateTransform Merotasi sebuah elemen dengan sudut
tertentu.

ScaleTransform Menskala sebuah elemen dengan nilai


ScaleX dan ScaleY tertentu.

SkewTransform Memiringkan sebuah elemen dengan


nilai AngleX dan AngleY tertentu.

TranslateTransform Memindahkan (translates) sebuah


elemen dengan nilai X dan Y tertentu.

Untuk menciptakan transformasi yang lebih kompleks, WPF menyediakan dua kelas
berikut:
75 WPF, Just Code It!

Tabel 4.3 Kelas Transform Khusus

Kelas Deskripsi
TransformGroup Mengelompokkan beberapa obyek TransformGroup kedalam sebuah
Transform tunggal yang kemudian dapat Anda terapkan untuk
mentransformasi properti.
MatrixTransform Menciptakan transformasi-transformasi khusus yang tidak disediakan
oleh kelas-kelas Transform lainnya. Ketika Anda menggunakan
sebuah MatrixTransform, Anda memanipulasi Matrix secara
langsung.

4.2.2 Transformasi Shapes

Transformasi yang umum diterapkan ke sebuah shape adalah rotasi. Untuk merotasi
sebuah shape, ciptakan sebuah RotateTransform dan tentukan Angle (sudut)-nya.
Tetapkan properti CenterX dan CenterY jika Anda ingin mengontrol pada titik mana
elemen dirotasi. Nilai-nilai properti ini diekspresikan didalam ruang koordinat elemen
yang sedang ditransformasikan. CenterX dan CenterY memiliki nilai-nilai default nol. Lalu
terapkan RotateTransform ke elemen tersebut. Jika Anda tidak ingin transformasi
mempengaruhi layout, tetapkan properti RenderTransform.

Pada contoh berikut, RotateTransform digunakan untuk merotasi sebuah shape 45


derajat pada pokok kiri atas shape (0,0).

XAML
<!—melakukan pemutaran bangun sebesar 45 (0,0). -->
<Polyline Points="25,25 0,50 25,75 50,50 25,25 25,0"
Stroke="Blue" StrokeThickness="10"
Canvas.Left="75" Canvas.Top="50">

<Polyline.RenderTransform>
<RotateTransform CenterX="0" CenterY="0" Angle="45" />
76 WPF, Just Code It!

</Polyline.RenderTransform>
</Polyline>

Didalam contoh berikut, shape lain dirotasi 45 derajat, namun kali ini ia dirotasi pada
titik (25,50).
XAML
<!—melakukan pemutaran bangun 45 derajat dari titik pusat -->
<Polyline
Points="25,25 0,50 25,75 50,50 25,25 25,0"
Stroke="Blue" StrokeThickness="10"
Canvas.Left="75" Canvas.Top="50"
RenderTransformOrigin="0.5,0.5">
<Polyline.RenderTransform>
<RotateTransform Angle="45" />
</Polyline.RenderTransform>
</Polyline>

Ilustrasi berikut menampilkan hasil penerapan dua transformasi.

Gambar 4.3 Ilustrasi penerapan transformasi

4.2.3 Mentransformasi Elemen-elemen

Seperti shapes yang dapat ditransformasikan, Anda dapat menerapkan obyek-obyek


Transform ke elemen-elemen untuk mengubah tampilan mereka. Karena semua elemen
WPF digambarkan oleh WPF, Anda dapat menerapkan sebuah Transform ke elemen
77 WPF, Just Code It!

WPF apapun. Catat bahwa sebuah Transform hanya mempengaruhi tampilan dari
sebuah kontrol. Fungsional dari sebuah kontrol tetap tidak terpengaruh, walaupun
menerapkan Transforms yang dramatis ke elemen-elemen UI dapat mempengaruhi
seberapa baik seorang pengguna dapat memahami dan menggunakan UI.

Anda dapat menerapkan sebuah Transform ke sebuah elemen dengan cara yang sama
jika Anda menerapkannya ke sebuah shape – dengan mengatur properti
RenderTransform. Contoh berikut mendemonstrasikan sebuah obyek Button dengan
SkewTransform diterapkan:

<Button Height="20" Width="50">


<Button.RenderTransform>
<SkewTransform AngleX="-30"></SkewTransform>
</Button.RenderTransform>
</Button>

4.2.4 Flipping

Salah satu model dalam transformasi adalah membalik (flip) sebuah elemen, yang
menyeberangi sumbu y secara horizontal atau menyeberangi sumbu x secara vertikal.
Anda dapat membalik sebuah elemen dengan menggunakan ScaleTransform.

 Untuk membalik sebuah elemen secara horizontal namun mempertahankan


bentuk dan ukurannya, set properti ScaleX bernilai –1.
 Untuk membalik sebuah elemen secara vertikal namun mempertahankan bentuk
dan ukurannya, set properti ScaleY bernilai –1.

Dengan menetapkan ScaleX maupun ScaleY dengan nilai –1 menghasilkan sebuah


elemen yang dibalik menyeberangi kedua sumbu. Contoh berikut mendemonstrasikan
pembalikan sebuah tombol secara horizontal:

<Button Height="50" Width="100" VerticalAlignment="Bottom">


<Button.RenderTransform>
78 WPF, Just Code It!

<ScaleTransform ScaleX="-1"></ScaleTransform>
</Button.RenderTransform>Flipped Button
</Button>

Dengan menggunakan konsep Transform diatas, Anda memindahkan elemen


menyeberangi sumbu x sehingga seolah-olah ia adalah sebuah gambar cermin.

Untuk membalik sebuah elemen namun mempertahankan posisi aslinya, atur properti
RenderTransformOrigin dengan nilai .5, .5, seperti yang ditampilkan dalam cetak tebal
berikut:

<Button RenderTransformOrigin=".5, .5" Height="50" Width="100"


VerticalAlignment="Bottom">
<Button.RenderTransform>
<ScaleTransform ScaleX="-1"></ScaleTransform>
</Button.RenderTransform>Flipped Button
</Button>

4.3 Brush

Brush memungkinkan Anda untuk melukiskan obyek-obyek UI dengan sederhana, warna


solid hingga serangkaian pola dan gambar yang kompleks. Sebuah Brush melukiskan
sebuah area dengan keluarannya. Brush yang berbeda menghasilkan jenis keluaran yang
berbeda. Beberapa brush melukiskan sebuah area dengan sebuah warna solid, lainnya
dengan sebuah gradien, pola atau gambar. Ilustrasi berikut menampilkan contoh dari
masing-masing tipe Brush yang berbeda.
79 WPF, Just Code It!

Gambar 4.4 Contoh-contoh Brush

Anda dapat mengubah tampilan sebuah kontrol dengan memberikan brush yang
berbeda ke salah satu propertinya. Berikut adalah beberapa properti dari Brush:

 Background: Brush yang diberikan ke properti ini melukis background kontrol.


 BorderBrush: Brush yang diberikan ke properti ini melukis border kontrol.
 Fill: Brush yang melukis interior sebuah shape.
 Foreground: Brush yang diberikan ke properti ini melukis foreground kontrol,
termasuk konten kontrol jika konten adalah sebuah string.
 OpacityMask: Properti ini menerima sebuah obyek Brush, namun hanya
komponen opacity dari brush ini yang dipertimbangkan. Opacity dari kontrol
akan ditentukan oleh opacity dari brush yang diberikan ke properti ini. Sebagai
contoh, jika Anda memberikan sebuah brush transparan ke properti ini,
keseluruhan kontrol tampil transparan. Anda dapat menggunakan brush-brush
yang eksotik untuk menciptakan efek-efek transparan yang eksotik dengan
properti ini.
 Stroke: Brush yang melukis tepi sebuah shape.
80 WPF, Just Code It!

Catat bahwa properti-properti ini merepresentasikan beberapa kontrol yang berbeda,


dan tidak ada kontrol yang memiliki semua properti ini.

Brushes adalah obyek yang freezable. Karenanya Anda dapat membuat perubahan ke
obyek-obyek Brush selama metode Freeze belum dipanggil. Setelah metode
Brush.Freeze dipanggil, brush menjadi read-only dan tidak ada perubahan yang dapat
dilakukan.

4.3.1 SolidColorBrush

SolidColorBrush adalah kelas Brush yang paling sederhana. Obyek SolidColorBrush,


seperti namanya, melukiskan sebuah warna solid tunggal tanpa pola atau gradient
apapun. Anda dapat mengakses brush-brush ini, seperti:

Brush aBrush;
aBrush = Brushes.AliceBlue;

Didalam Extensible Application Markup Language (XAML), Anda dapat memberikan


sebuah brush yang diberi nama ke sebuah properti hanya dengan mengacu ke namanya,
seperti:

<Button Background="Tomato"></Button>

Anda juga dapat menggunakan notasi heksadesimal untuk menetapkan brush didalam
XAML. Ketika menggunakan notasi heksadesimal, Anda menspesifikasikan sebuah
nomor heksadesimal delapan digit yang mendefinisikan warna. Pasangat pertama dari
digit (dari 00 hingga FF) menAndakan nilai opacity. Pasangan kedua dari digit
menunjukkan kekuatan dari Red channel. Set ketiga menunjukkan kekuatan dari Green
channel, dan pasangan terakhir menunjukkan kekuatan dari Blue channel. Nomor
heksadesimal diawali dengan sebuah #. Contoh berikut memperlihatkan pengaturan
background dari sebuah tombol menjadi obyek SolidColorBrush merah murni:

<Button Background="#FFFF0000"></Button>
81 WPF, Just Code It!

Anda juga dapat menciptakan sebuah obyek SolidColorBrush baru dengan mengatur
nilai dari masing-masing channel secara langsung, seperti:

<Button>
<Button.Background>
<SolidColorBrush>
<SolidColorBrush.Color>
<Color A="255" R="0" G="0" B="255"/>
</SolidColorBrush.Color>
</SolidColorBrush>
</Button.Background>
</Button>

Didalam kode, Anda dapat menggunakan metode Color.FromArgb untuk


menggambarkan channel-channel individual, seperti:

SolidColorBrush aBrush;
aBrush = new SolidColorBrush(Color.FromArgb(255, 0, 255, 0));

Contoh berikut menggunakan SolidColorBrush untuk melukiskan Fill dari sebuah


Rectangle.

C#
Rectangle exampleRectangle = new Rectangle();
exampleRectangle.Width = 75;
exampleRectangle.Height = 75;

// Create a SolidColorBrush and use it to paint the rectangle.


SolidColorBrush myBrush = new SolidColorBrush(Colors.Red);
exampleRectangle.Fill = myBrush;

XAML
<Rectangle Width="75" Height="75">
<Rectangle.Fill>
<SolidColorBrush Color="Red" />
</Rectangle.Fill>
</Rectangle>
82 WPF, Just Code It!

Hasilnya adalah:

Gambar 4.5 Sebuah Rectangle yang dilukis menggunakan SolidColorBrush

4.3.2 LinearGradientBrush

LinearGradientBrush melukiskan sebuah area dengan gradien linier. Gradien linier


mencampurkan dua atau lebih warna sepanjang sebuah garis, yaitu sumbu gradien.
Anda menggunakan obyek-obyek GradientStop untuk menentukan warna-warna
didalam gradien dan posisi mereka.

Contoh berikut menggunakan sebuah LinearGradientBrush untuk melukiskan Fill dari


sebuah Rectangle.

Gambar 4.6 Sebuah Rectangle yang dilukis menggunakan LinearGradientBrush

C#
Rectangle exampleRectangle = new Rectangle();
exampleRectangle.Width = 75;
exampleRectangle.Height = 75;

// Create a LinearGradientBrush and use it to paint the rectangle.


LinearGradientBrush myBrush = new LinearGradientBrush();
myBrush.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0));
myBrush.GradientStops.Add(new GradientStop(Colors.Orange, 0.5));
83 WPF, Just Code It!

myBrush.GradientStops.Add(new GradientStop(Colors.Red, 1.0));

exampleRectangle.Fill = myBrush;

XAML
<Rectangle Width="75" Height="75">
<Rectangle.Fill>
<LinearGradientBrush>
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="Orange" Offset="0.5" />
<GradientStop Color="Red" Offset="1.0" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>

Obyek LinearGradientBrush menggunakan sistem koordinat untuk menentukan


bagaimana gradient disusun. Sistem koordinat didasarkan pada sebuah persegi yang
membatasi area untuk dilukis. Pojok kiri atas dari persegi ini adalah koordinat (0,0), dan
pojok kanan bawah adalah koordinat (1,1). Koordinat berhubungan dengan ukuran dari
area gambar dan tidak terkait dengan piksel-piksel aktual.
Setiap LinearGradientBrush memuat sekumpulan obyek GradientStop, yang masing-
masing mengekspos dua properti penting: Color dan Offset. Properti Color menentukan
warna yang dicampur, dan Offset adalah sebuah nomor yang menspesifikasikan titik
didalam sistem koordinat dimana warna yang ditunjuk adalah murni dan tidak dicampur
dengan warna-warna lain.

Gradien dengan pencampuran warna-warna terjadi dalam sebuah garis yang berjalan
dari titik awal sampai titik akhir. Secara default, titik awal adalah (0,0), dan titik akhir
adalah (1,1), yang menciptakan sebuah gradient diagonal yang bercampur dari pojok kiri
atas ke pojok kanan bawah. Anda dapat menspesifikasikan titik-titik awal dan akhir
lainnya untuk LinearGradientBrush dengan menggunakan properti
LinearGradientBrush.StartPoint dan LinearGradientBrush.EndPoint. Garis yang
mendefinisikan gradien tidak perlu mulai dari pojok sistem koordinat. Sebagai contoh,
84 WPF, Just Code It!

Anda dapat menciptakan sebuah LinearGradientBrush dengan StartPoint (.3,.3) dan


EndPoint (.7,.7), atau pasangan koordinat lain dengan nilai antara 0 dan 1.

Ketika garis yang menggambarkan gradien tidak meregang dari satu ujung sistem
koordinat ke ujung lainnya, nilai dari properti LinearGradientBrush.Spread menentukan
bagaimana sisa dari area tersebut dilukiskan. Nilai dan efek yang mungkin dari properti
ini:

 Pad: Ini adalah nilai default untuk properti Spread. Ia menggunakan warna solid
pada salah satu sisi dari titik awal gradien.
 Reflect: Ketika SpreadMethod diset dengan Reflect, gradien diperluas dalam
orientasi sebaliknya, seperti sebuah gambar cermin.
 Repeat: Ketika SpreadMethod diset dengan Repeat, gradien diulangi dalam
orientasi yang sama.

4.3.3 RadialGradientBrush

Obyek RadialGradientBrush sangat mirip dengan obyek LinearGradientBrush—yang


mencampur serangkaian warna sepanjang gradien. RadialGradientBrush memuat
sekumpulan obyek GradientStop yang menentukan bagaimana gradien dibangun.
Perbedaan kuncinya adalah bahwa gradien menyebar keluar didalam lingkaran-
lingkaran konsentrik dari sebuah titik didalam sistem koordinat. Pusat dari gradien
digambarkan oleh properti RadialGradientBrush.GradientOrigin (.5, .5 secara default).
Lingkaran terluar dari RadialGradientBrush digambarkan oleh properti RadiusX dan
RadiusY. RadiusX menentukan jarak dari lingkaran terluar didalam dimensi vertikal, dan
RadiusY menentukannya dalam dimensi horizontal.
85 WPF, Just Code It!

Gambar 4.7 Sebuah Rectangle yang dilukis menggunakan RadialGradientBrush

C#
Rectangle exampleRectangle = new Rectangle();
exampleRectangle.Width = 75;
exampleRectangle.Height = 75;

// Create a RadialGradientBrush and use it to paint the rectangle.


RadialGradientBrush myBrush = new RadialGradientBrush();
myBrush.GradientOrigin = new Point(0.75, 0.25);
myBrush.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0));
myBrush.GradientStops.Add(new GradientStop(Colors.Orange, 0.5));
myBrush.GradientStops.Add(new GradientStop(Colors.Red, 1.0));

exampleRectangle.Fill = myBrush;

XAML
<Rectangle Width="75" Height="75">
<Rectangle.Fill>
<RadialGradientBrush GradientOrigin="0.75,0.25">
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="Orange" Offset="0.5" />
<GradientStop Color="Red" Offset="1.0" />
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>

4.3.4 ImageBrush
86 WPF, Just Code It!

Obyek ImageBrush mengijinkan Anda untuk melukis obyek-obyek menggunakan sebuah


gambar sebagai sumber untuk brush. Anda dapat menetapkan gambar sumber untuk
sebuah ImageBrush dengan menetapkan properti ImageSource, seperti:

C#
Rectangle exampleRectangle = new Rectangle();
exampleRectangle.Width = 75;
exampleRectangle.Height = 75;

// Create an ImageBrush and use it to paint the rectangle.


ImageBrush myBrush = new ImageBrush();
myBrush.ImageSource = new BitmapImage(new
Uri(@"sampleImages\cherry.jpg", UriKind.Relative));
exampleRectangle.Fill = myBrush;

XAML
<Rectangle Width="75" Height="75">
<Rectangle.Fill>
<ImageBrush ImageSource="sampleImages\cherry.jpg" />
</Rectangle.Fill>
</Rectangle>

Gambar 4.8 Sebuah Rectangle yang dilukis menggunakan ImageBrush

ImageBrush menggunakan gambar yang ditunjuk untuk melukis obyek-obyek visual yang
terkait dengannya. Jika gambar yang ditunjuk lebih kecil daripada obyek visual yang
diberikan ke brush, bagaimana brush melukis obyek dikontrol oleh nilai properti Stretch.
Nilai-nilai yang mungkin dari properti Stretch:
87 WPF, Just Code It!

 Fill: Gambar diregangkan dalam kedua dimensi untuk mengisi ruang yang
tersedia. Aspek rasio gambar tidak dipertahankan.
 None: Gambar dilukis pada ukuran aslinya. Area diluar ukuran gambar asli tidak
dilukis.
 Uniform: Gambar diregangkan untuk mengisi dimensi dari ruang yang tersedia,
namun aspek rasio gambar dipertahankan. Area diluar ukuran yang diregangkan
tidak dilukis.
 UniformToFill: Gambar diperluas untuk mengisi semua ruang lukis yang tersedia.
Aspek rasio dipertahankan, namun konten dapat dipotong jika aspek rasio
gambar berbeda dari aspek rasio kontainer.

4.3.5 VisualBrush

Obyek VisualBrush sangat mirip dengan obyek ImageBrush, namun ia tidak


menggunakan sebuah gambar sebagai sumber untuk melukis, melainkan menggunakan
sebuah elemen visual, seperti sebuah kontrol WPF atau elemen lain yang diturunkan
oleh kelas Visual. Anda dapat menggunakan sebuah VisualBrush sama seperti Anda
menggunakan sebuah ImageBrush, yang menerapkan properti Stretch atau TileMode.

Gambar 4.9 Sebuah Rectangle yang dilukis menggunakan VisualBrush

C#
Rectangle exampleRectangle = new Rectangle();
exampleRectangle.Width = 75;
exampleRectangle.Height = 75;

// Create a VisualBrush and use it to paint the rectangle.


88 WPF, Just Code It!

VisualBrush myBrush = new VisualBrush();

// Create the brush's contents.


StackPanel aPanel = new StackPanel();

// Create a DrawingBrush and use it to paint the panel.


DrawingBrush myDrawingBrushBrush = new DrawingBrush();
GeometryGroup aGeometryGroup = new GeometryGroup();
aGeometryGroup.Children.Add(new RectangleGeometry(new Rect(0, 0, 50, 50)));
aGeometryGroup.Children.Add(new RectangleGeometry(new Rect(50, 50, 50, 50)));

RadialGradientBrush checkerBrush = new RadialGradientBrush();


checkerBrush.GradientStops.Add(new GradientStop(Colors.MediumBlue, 0.0));
checkerBrush.GradientStops.Add(new GradientStop(Colors.White, 1.0));

GeometryDrawing checkers = new GeometryDrawing(checkerBrush, null,


aGeometryGroup);
myDrawingBrushBrush.Drawing = checkers;
aPanel.Background = myDrawingBrushBrush;

// Create some text.


TextBlock someText = new TextBlock();
someText.Text = "Hello, World";
FontSizeConverter fSizeConverter = new FontSizeConverter();
someText.FontSize = (double)fSizeConverter.ConvertFromString("10pt");
someText.Margin = new Thickness(10);

aPanel.Children.Add(someText);
myBrush.Visual = aPanel;
exampleRectangle.Fill = myBrush;

XAML
<Rectangle Width="75" Height="75">
<Rectangle.Fill>
<VisualBrush TileMode="Tile">
<VisualBrush.Visual>
<StackPanel>
<StackPanel.Background>
89 WPF, Just Code It!

<DrawingBrush>
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Brush>
<RadialGradientBrush>
<GradientStop Color="MediumBlue" Offset="0.0" />
<GradientStop Color="White" Offset="1.0" />
</RadialGradientBrush>
</GeometryDrawing.Brush>
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,50,50" />
<RectangleGeometry Rect="50,50,50,50" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</StackPanel.Background>
<TextBlock FontSize="10pt" Margin="10">Hello,
World!</TextBlock>
</StackPanel>
</VisualBrush.Visual>
</VisualBrush>
</Rectangle.Fill>
</Rectangle>

4.4 Drawing

Sebuah obyek Drawing menggambarkan konten yang terlihat, seperti sebuah shape,
bitmap, video, atau sebaris teks.

4.4.1 Menggambar sebuah Shape

Untuk menggambar sebuah shape, gunakan GeometryDrawing. Properti Geometry


menggambarkan shape yang akan digambarkan, properti Brush menggambarkan
90 WPF, Just Code It!

bagaimana interior shape harus dilukiskan, dan properti Pen menggambarkan


bagaimana outline harus digambarkan.

Contoh berikut menggunakan GeometryDrawing untuk menggambar sebuah shape.


Shape digambarkan oleh sebuah GeometryGroup dan dua obyek EllipseGeometry.
Interior shape dilukiskan dengan LinearGradientBrush dan outlinenya digambarkan
dengan sebuah Pen warna Black.

Gambar 4.10 Sebuah GeometryDrawing

C#
// membuat geometri
GeometryGroup ellipses = new GeometryGroup();
ellipses.Children.Add(new EllipseGeometry(new Point(50,50), 45, 20));
ellipses.Children.Add(new EllipseGeometry(new Point(50, 50), 20, 45));

// menggambar geometri gambar.


GeometryDrawing aGeometryDrawing = new GeometryDrawing();
aGeometryDrawing.Geometry = ellipses;

// menggabarkannya dengan gradien.


aGeometryDrawing.Brush =
new LinearGradientBrush(
Colors.Blue,
Color.FromRgb(204,204,255),
new Point(0,0),
new Point(1,1));

// menggambar drawing
aGeometryDrawing.Pen = new Pen(Brushes.Black, 10);
91 WPF, Just Code It!

XAML
<GeometryDrawing>
<GeometryDrawing.Geometry>

<!-- Create a composite shape. -->


<GeometryGroup>
<EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
<EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>

<!-- Paint the drawing with a gradient. -->


<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Blue" />
<GradientStop Offset="1.0" Color="#CCCCFF" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
<GeometryDrawing.Pen>

<!-- Outline the drawing with a solid color. -->


<Pen Thickness="10" Brush="Black" />
</GeometryDrawing.Pen>
</GeometryDrawing>

4.4.2 Menggambar sebuah Image

Untuk menggambarkan sebuah image, gunakan ImageDrawing. Properti ImageSource


menggambarkan image yang digambarkan, dan properti Rect menggambarkan daerah
dimana image digambarkan.

Contoh berikut menggambarkan sebuah image kedalam sebuah rectangle yang terletak
pada (75,75) dari 100 x 100 pixel.
92 WPF, Just Code It!

Gambar 4.11 ImageDrawing 100x100

C#
// menampilkan image (75,75).
ImageDrawing bigKiwi = new ImageDrawing();
bigKiwi.Rect = new Rect(75, 75, 100, 100);
bigKiwi.ImageSource = new BitmapImage(
new Uri(@"sampleImages\kiwi.png", UriKind.Relative));

XAML
<!-- The Rect property specifies that the image only fill a 100 by 100
rectangular area. -->
<ImageDrawing Rect="75,75,100,100"
ImageSource="sampleImages\kiwi.png"/>

4.4.3 Menggambar Text

Untuk menggambarkan teks, gunakan GlyphRunDrawing dan GlyphRun. Contoh berikut


menggunakan GlyphRunDrawing untuk menggambarkan teks "Hello World".

C#
GlyphRun theGlyphRun = new GlyphRun(
new GlyphTypeface(new Uri(@"C:\WINDOWS\Fonts\TIMES.TTF")),
0,
false,
13.333333333333334,
new ushort[]{43, 72, 79, 79, 82, 3, 58, 82, 85, 79, 71},
93 WPF, Just Code It!

new Point(0, 12.29),


new double[]{
9.62666666666667, 7.41333333333333, 2.96,
2.96, 7.41333333333333, 3.70666666666667,
12.5866666666667, 7.41333333333333,
4.44, 2.96, 7.41333333333333},
null,
null,
null,
null,
null,
null
);

GlyphRunDrawing gDrawing = new GlyphRunDrawing(Brushes.Black,


theGlyphRun);

XAML
<GlyphRunDrawing ForegroundBrush="Black">
<GlyphRunDrawing.GlyphRun>
<GlyphRun
CaretStops="{x:Null}"
ClusterMap="{x:Null}"
IsSideways="False"
GlyphOffsets="{x:Null}"
GlyphIndices="43 72 79 79 82 3 58 82 85 79 71"
BaselineOrigin="0,12.29"
FontRenderingEmSize="13.333333333333334"
DeviceFontName="{x:Null}"
AdvanceWidths="9.62666666666667 7.41333333333333 2.96 2.96
7.41333333333333 3.70666666666667 12.5866666666667 7.41333333333333
4.44 2.96 7.41333333333333"
BidiLevel="0">
<GlyphRun.GlyphTypeface>
<GlyphTypeface FontUri="C:\WINDOWS\Fonts\TIMES.TTF" />
</GlyphRun.GlyphTypeface>
</GlyphRun>
94 WPF, Just Code It!

</GlyphRunDrawing.GlyphRun>
</GlyphRunDrawing>

4.4.4 Menggabungkan Drawings

DrawingGroup mengijinkan Anda untuk menggabungkan beberapa drawings kedalam


sebuah drawing gabungan tunggal. Dengan menggunakan DrawingGroup, Anda dapat
menggabungkan shapes, images, dan text kedalam sebuah obyek Drawing tunggal.

Contoh berikut menggunakan DrawingGroup untuk menggabungkan dua obyek


GeometryDrawing dan sebuah obyek ImageDrawing.

Gambar 4.12 Drawing Gabungan

C#
// Create three drawings.
GeometryDrawing ellipseDrawing =
new GeometryDrawing(
new SolidColorBrush(Color.FromArgb(102, 181, 243, 20)),
new Pen(Brushes.Black, 4),
new EllipseGeometry(new Point(50,50), 50, 50)
);

ImageDrawing kiwiPictureDrawing =
new ImageDrawing(
new BitmapImage(new Uri(@"sampleImages\kiwi.png",
95 WPF, Just Code It!

UriKind.Relative)),
new Rect(50,50,100,100));

GeometryDrawing ellipseDrawing2 =
new GeometryDrawing(
new SolidColorBrush(Color.FromArgb(102,181,243,20)),
new Pen(Brushes.Black, 4),
new EllipseGeometry(new Point(150, 150), 50, 50)
);

// Create a DrawingGroup to contain the drawings.


DrawingGroup aDrawingGroup = new DrawingGroup();
aDrawingGroup.Children.Add(ellipseDrawing);
aDrawingGroup.Children.Add(kiwiPictureDrawing);
aDrawingGroup.Children.Add(ellipseDrawing2);

XAML
<DrawingGroup>
<GeometryDrawing Brush="#66B5F314">
<GeometryDrawing.Geometry>
<EllipseGeometry Center="50,50" RadiusX="50" RadiusY="50"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="4" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<ImageDrawing ImageSource="sampleImages\kiwi.png"
Rect="50,50,100,100"/>
<GeometryDrawing Brush="#66B5F314">
<GeometryDrawing.Geometry>
<EllipseGeometry Center="150,150" RadiusX="50" RadiusY="50"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="4" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
96 WPF, Just Code It!

4.5 Menampilkan Drawing sebagai Image

Untuk menampilkan sebuah Drawing dengan kontrol Image, gunakan DrawingImage


sebagai Source kontrol Image dan tetapkan properti DrawingImage..::.Drawing ke
drawing yang ingin Anda tampilkan.

Contoh berikut menggunakan DrawingImage dan sebuah kontrol Image untuk


menampilkan sebuah GeometryDrawing

Gambar 4.13 DrawingImage

C#
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SDKSample
{
public class DrawingImageExample : Page
{
public DrawingImageExample()
{
// Create the Geometry to draw.
GeometryGroup ellipses = new GeometryGroup();
ellipses.Children.Add(
new EllipseGeometry(new Point(50,50), 45, 20)
);

ellipses.Children.Add(
97 WPF, Just Code It!

new EllipseGeometry(new Point(50, 50), 20, 45)


);

// Create a GeometryDrawing.
GeometryDrawing aGeometryDrawing = new GeometryDrawing();
aGeometryDrawing.Geometry = ellipses;

// Paint the drawing with a gradient.


aGeometryDrawing.Brush =
new LinearGradientBrush(
Colors.Blue,
Color.FromRgb(204,204,255),
new Point(0,0),
new Point(1,1));

// Outline the drawing with a solid color.


aGeometryDrawing.Pen = new Pen(Brushes.Black, 10);

// Use a DrawingImage and an Image control


// to display the drawing.
DrawingImage geometryImage = new
DrawingImage(aGeometryDrawing);

// Freeze the DrawingImage for performance benefits.


geometryImage.Freeze();

Image anImage = new Image();


anImage.Source = geometryImage;
anImage.HorizontalAlignment = HorizontalAlignment.Left;

// Place the image inside a border and


// add it to the page.
Border exampleBorder = new Border();
exampleBorder.Child = anImage;
exampleBorder.BorderBrush = Brushes.Gray;
exampleBorder.BorderThickness = new Thickness(1);
exampleBorder.HorizontalAlignment =
HorizontalAlignment.Left;
98 WPF, Just Code It!

exampleBorder.VerticalAlignment = VerticalAlignment.Top;
exampleBorder.Margin = new Thickness(10);

this.Margin = new Thickness(20);


this.Background = Brushes.White;
this.Content = exampleBorder;
}
}
}

XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml
/presentation/options"
xmlns:mc="http://schemas.openxmlformats.org/markup-
compatibility/2006"
mc:Ignorable="PresentationOptions"
Background="White" Margin="20">

<Border BorderBrush="Gray" BorderThickness="1"


HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="10">

<!-- This image uses a Drawing object for its source. -->
<Image>
<Image.Source>
<DrawingImage PresentationOptions:Freeze="True">
<DrawingImage.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry Center="50,50" RadiusX="45"
RadiusY="20" />
<EllipseGeometry Center="50,50" RadiusX="20"
99 WPF, Just Code It!

RadiusY="45" />
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Blue" />
<GradientStop Offset="1.0" Color="#CCCCFF" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
<GeometryDrawing.Pen>
<Pen Thickness="10" Brush="Black" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Border>
</Page>

4.6 Geometry

Kelas Geometry dan kelas-kelas yang diturunkannya mengijinkan Anda untuk


mendeskripsikan geometri shape 2-D. Deskripsi geometrik ini memiliki banyak
kegunaan, yaitu menggambarkan sebuah shape untuk dilukiskan ke layar, hit-test, clip
regions, bahkan sebuah path animasi.

Obyek-obyek Geometry bisa sederhana, seperti rectangles (persegi) dan circles


(lingkaran), atau gabungan, yang diciptakan dari dua atau lebih obyek geometri.
Geometri yang lebih kompleks dapat diciptakan dengan menggunakan kelas
PathGeometry dan StreamGeometry, yang memungkinkan Anda untuk menguraikan
busur lingkaran dan kurva.

Karena sebuah Geometry adalah sebuah tipe dari Freezable, obyek-obyek Geometry
menyediakan beberapa fitur khusus: mereka dapat dideklarasikan sebagai resources,
100 WPF, Just Code It!

yang dibagi antara banyak obyek, dibuat read-only untuk meningkatkan performa,
diklon dan dibuat thread-safe.

4.6.1 Geometries vs. Shapes

Kelas Geometry dan Shape terlihat mirip karena mereka berdua mendeskripsikan shape-
shape 2-D, namun ada beberapa perbedaan penting.

 Kelas Geometry diturunkan dari kelas Freezable sedangkan kelas Shape


diturunkan dari FrameworkElement.
 Karena berupa elemen, obyek-obyek Shape dapat merender dirinya sendiri dan
mengambil bagian dalam sistem layout, sedangkan obyek-obyek Geometry tidak
bisa melakukannya.

Walaupun obyek-obyek Shape lebih siap dipakai daripada obyek-obyek Geometry,


obyek-obyek Geometry lebih serbaguna. Sementara sebuah obyek Shape digunakan
untuk merender grafik-grafik 2-D, sebuah obyek Geometry dapat digunakan untuk
menggambarkan wilayah geometrik untuk grafik-grafik 2-D, menggambarkan wilayah
untuk clipping (pemotongan), atau menggambarkan wilayah untuk pengujian hit.

4.6.2 Path

Path adalah shape yang paling kompleks didalam WPF. Sebuah obyek Path menguraikan
sebuah shape yang kompleks yang dapat dibangun dari satu atau lebih obyek Geometry.
Sebuah obyek Geometry dapat dianggap sebagai sebuah blueprint untuk sebuah Shape.
Ia memuat semua data mengenai tampilan dari sebuah shape, seperti koordinat dan
ukuran, namun ia tidak menyertakan event-handling atau fungsionalitas berbasis
kontrol dari sebuah Shape.

Jenis obyek-obyek Geometry yang dapat digunakan untuk menciptakan sebuah Path:
101 WPF, Just Code It!

 CombinedGeometry: Menggabungkan dua obyek Geometry kedalam sebuah


obyek tunggal dan mengijinkan Anda untuk menerapkan efek-efek yang berbeda
dengan mengatur properti CombineMode.
 EllipseGeometry: Memuat data yang merepresentasikan shape dari sebuah
Ellipse.
 GeometryGroup: Merepresentasikan sekumpulan obyek Geometry yang
ditambahkan ke Path.
 LineGeometry: Merepresentasikan sebuah garis lurus.
 PathGeometry: Merepresentasikan sebuah shape atau figur yang kompleks yang
disusun dari garis, panah dan kurva.
 RectangleGeometry: Merepresentasikan sebuah persegi.
 StreamGeometry: Setara dengan PathGeometry. Perbedaannya adalah setelah
diciptakan ia bersifat read-only.

Cara paling sederhana untuk menciptakan sebuah Path adalah menambahkan sebuah
obyek Geometry tunggal ke properti Path.Data, seperti:

<Path Fill="Aqua">
<Path.Data>
<EllipseGeometry RadiusX="40" RadiusY="50"/>
</Path.Data>
</Path>

Anda dapat menciptakan paths yang terdiri dari bayak shape dengan menggunakan
kelas GeometryGroup. Contoh berikut menambahkan sebuah persegi dan sebuah elips:

<Path Fill="Aqua" Margin="100">


<Path.Data>
<GeometryGroup FillRule="Nonzero">
<EllipseGeometry RadiusX="40" RadiusY="50"/>
<RectangleGeometry Rect="0,0,10,100"/>
</GeometryGroup>
</Path.Data>
</Path>
102 WPF, Just Code It!

Ketika sebuah GeometryGroup memuat obyek-obyek Geometry yang saling tumpang


tindih, ia menentukan bagaimana area-area yang tumpang tindih diisi oleh nilai properti
FillRule, seperti dengan Polygon dan Polyline.

Kelas CombinedGeometry mengijinkan Anda untuk menciptakan obyek-obyek Geometry


yang merepresentasikan kombinasi dari dua obyek Geometry. Tipe kombinasi
ditentukan oleh properti GeometryCombineMode. Nilai-nilai untuk properti
GeometryCombineMode:

 Exclude: Obyek Geometry yang dihasilkan merepresentasikan area yang


dihasilkan ketika obyek Geometry kedua dikurangkan dari obyek Geometry
pertama.
 Intersect: Obyek Geometry yang dihasilkan merepresentasikan perpotongan dua
obyek Geometry masukan.
 Xor: Obyek Geometry yang dihasilkan merepresentasikan area yang tidak dibagi
antara dua obyek Geometry masukan. Ini adalah kebalikan dari nilai Intersect.
 Union: Obyek Geometry yang dihasilkan merepresentasikan gabungan dari dua
obyek Geometry masukan.

Contoh berikut mendemonstrasikan sebuah Path yang diciptakan menggunakan sebuah


obyek CombinedGeometry:

<Path Fill="Aqua" Margin="100">


<Path.Data>
<CombinedGeometry GeometryCombineMode="Exclude">
<CombinedGeometry.Geometry1>
<EllipseGeometry RadiusX="40" RadiusY="50"/>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<RectangleGeometry Rect="0,0,10,100"/>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
103 WPF, Just Code It!

Shape yang amat sangat kompleks dapat diciptakan menggunakan kelas PathGeometry.

4.6.3 Clipping

Anda juga dapat menggunakan obyek-obyek Geometry untuk memotong shape dari
elemen-elemen dengan mengatur properti Clip, yang diekspos oleh semua elemen WPF.
Mengatur properti Clip membatasi tampilan visual dari kontrol yang dipengaruhi ke
shape yang dijelaskan oleh obyek Geometry yang properti Clip nya diset. Ini tidak
mentransformasi elemen dengan cara apapun; ia memotong batasan-batasan yang
terlihat dari kontrol agar cocok dengan obyek Geometry.

Gambar 4.14 Clip elemen Button

Gambar 4.14 memperlihatkan dua elemen Button yang berukuran sama. Button kiri
properti Clip nya tidak diset, sedangkan Button kanan properti Clip nya diset ke obyek
EllipseGeometry.

4.7 Kesimpulan

Pada bagian ini dikemukakan berbagai obyek-obyek visual yang dimiliki oleh pustaka
WPF. Obye-obyek ini tentu siap pakai dalam membantu pengembang untuk
memvisualisasikan aplikasi yang lebih hidup dan lebih estetik. Selain berupa bentuk-
104 WPF, Just Code It!

bentuk bangun, WPF juga mendukung berbagai macam manipulasi trensformasi bangun
yang umum ada di dunia animasi seperti pergeseran, rotasi, pencerminan, hingga
pergerakan dinamis.
105 WPF, Just Code It!

5 Kontrol-kontrol WPF

WPF dikemas dengan banyak komponen umum UI yang digunakan hampir dalam semua
aplikasi Windows, seperti Button, Label, TextBox, Menu, dan ListBox. Bab ini akan
membahas beberapa kontrol yang paling sering digunakan dalam aplikasi WPF yaitu
Label, Button, CheckBox, RadioButton, TextBlock, Image, TextBox, ComboBox, ListBox,
TreeView, Menu dan Toolbar.

5.1 Kontrol Label

Kontrol Label adalah salah satu kontrol WPF yang paling sederhana dan paling banyak
digunakan. Kontrol ini biasanya menyediakan informasi didalam UI. Menurut sejarah,
sebuah Label hanya memuat teks saja, namun karena Label yang dikemas dengan WPF
adalah sebuah ContentControl, ia dapat memuat teks, bisa juga memuat UIElement.

Penggunaan umum untuk sebuah kontrol Label adalah sebagai berikut:

<Label Name="label1">This is a Label</Label>

5.1.1 Label dan Kunci Mnemonik

Label memiliki dukungan built-in untuk kunci-kunci mnemonik. Ini adalah kunci-kunci
yang memindahkan fokus ke sebuah kontrol yang ditunjuk ketika kunci ALT ditekan
dengan kunci mnemonik. Sebagai contoh, jika R adalah kunci mnemonik untuk sebuah
kontrol, fokus akan berpindah ke kontrol tersebut ketika ditekan ALT+R.

Label dan kunci mnemonik sering digunakan untuk memungkinkan akses cepat
keyboard ke kontrol-kontrol seperti sebuah TextBox. Gambar berikut menampilkan
sebuah Label "Themes" yang bertarget sebuah ComboBox. Ketika pengguna menekan
ALT+T, ComboBox menerima fokus.
106 WPF, Just Code It!

Gambar 5.1 Label dan Kunci Mnemonik

Kunci mnemonik ditetapkan dengan memberi awalan simbol underscore (_) pada kunci
yang diinginkan, dan tampil bergaris bawah pada run time ketika kunci ALT ditekan.
Sebagai contoh, kode berikut tampil sebagai Press Alt+A pada run time ketika kunci
ALT telah ditekan:

<Label>Press Alt+_A</Label>

Untuk memasukkan sebuah Label ke sebuah Control, tetapkan properti Target ke


kontrol yang harus mendapatkan fokus ketika pengguna menekan kunci akses. Contoh
berikut mendemonstrasikan bagaimana cara menciptakan sebuah kunci mnemonik
dengan sebuah kontrol target bernama TextBox1:

<Label Target="{Binding ElementName=TextBox1}" Height="27"


HorizontalAlignment="Left" VerticalAlignment="Top" Width="51">_Name
</Label>

<TextBox Name="TextBox1" Margin="53,1,94,0" Height="26"


VerticalAlignment="Top">
</TextBox>

5.2 Kontrol Button


107 WPF, Just Code It!

Kontrol Button bereaksi atas masukan pengguna dari sebuah mouse, keyboard, stylus,
atau perangkat masukan lainnya. Button dirancang untuk mengizinkan pengguna
membuat sebuah pilihan, menutup sebuah kotak dialog, atau melakukan aksi lainnya.
Anda dapat mengeksekusi kode ketika button diklik dengan menangani event Click.
Button adalah sebuah komponen UI dasar yang dapat memuat konten
sederhana, seperti teks, dan juga dapat memuat konten yang kompleks, seperti kontrol-
kontrol Panel dan Images.

Gambar 5.2 Button dalam keadaan default, mendapatkan fokus, dan ditekan

Kontrol Button mengekspos dua properti penting yang membuatnya berguna ketika
membangun UI, yaitu properti IsDefault dan IsCancel.

 Properti IsDefault menentukan apakah sebuah button dijadikan sebagai button


default untuk UI. Ketika IsDefault ditetapkan dengan nilai True, event Click dari
button tersebut dibangkitkan ketika kunci Enter ditekan.
 Properti IsCancel menentukan apakah button harus dijadikan sebuah button
Cancel. Ketika IsCancel diberi nilai True, event Click dari button tersebut
dibangkitkan ketika kunci Esc ditekan.

5.3 Kontrol CheckBox

Anda dapat menggunakan sebuah CheckBox didalam UI aplikasi Anda untuk


merepresentasikan opsi-opsi yang dapat dipilih atau dibersihkan oleh pengguna. Anda
dapat menggunakan sebuah checkbox tunggal atau Anda dapat mengelompokkan dua
atau lebih checkbox.
108 WPF, Just Code It!

Gambar 5.3 Kontrol CheckBox dalam berbagai keadaan

Kontrol Checkbox sebenarnya diturunkan dari kelas ButtonBase dan biasanya digunakan
untuk mengizinkan pengguna untuk memilih apakah sebuah opsi dipilih atau tidak. Anda
dapat menentukan apakah sebuah checkbox dipilih atau tidak dengan mengakses
properti IsChecked.

Karena Checkbox diturunkan dari ButtonBase, ia membangkitkan sebuah event Click


kapanpun checkbox dipilih atau dibersihkan oleh pengguna. Cara terbaik untuk bereaksi
atas sebuah checkbox yang sedang dipilih atau dibersihkan adalah menangani event
Click.

5.4 Kontrol RadioButton

Seperti Checkbox, RadioButton diturunkan dari kelas ButtonBase. Kontrol RadioButton


biasanya dikelompokkan bersama untuk menawarkan sebuah pilihan tunggal diantara
beberapa opsi kepada pengguna, dan hanya satu button yang dapat dipilih pada satu
waktu. Dengan klik sebuah radio button membangkitkan event Click, yang dapat
digunakan untuk bereaksi atas pilihan pengguna.

Sebuah fitur fundamental dari kontrol RadioButton adalah bahwa mereka dapat
dikelompokkan. Didalam sekelompok kontrol RadioButton, memilih salah satunya
secara otomatis membersihkan yang lainnya. Karenanya, tidak mungkin lebih dari satu
radio button didalam sebuah grup dipilih pada satu waktu.
109 WPF, Just Code It!

Gambar 5.4 RadioButton

Biasanya, semua kontrol RadioButton didalam sebuah kontainer tunggal secara otomatis
didalam grup yang sama. Jika Anda ingin memiliki sebuah grup tinggal dari tiga kontrol
RadioButton didalam sebuah jendela, yang perlu Anda lakukan adalah menambahkan
ketiganya ke jendela Anda – mereka secara otomatis dikelompokkan. Anda dapat
memiliki banyak grup didalam sebuah kontainer tunggal dengan menetapkan properti
GroupName.

Contoh berikut mendemonstrasikan dua grup yang masing-masing terdiri dari dua radio
button:

<RadioButton GroupName="Group1" Name="RadioButton1" Height="22"


VerticalAlignment="Top" Margin="15,10,0,0"
HorizontalAlignment="Left" Width="76">Button 1
</RadioButton>

<RadioButton GroupName="Group1" Name="RadioButton2"


Margin="15,34,0,0" Height="22" VerticalAlignment="Top"
HorizontalAlignment="Left" Width="76">Button 2
</RadioButton>

<RadioButton GroupName="Group2" Name="RadioButton3"


Margin="15,58,0,0" Height="21" HorizontalAlignment="Left"
VerticalAlignment="Top" Width="76">Button 3
</RadioButton>

<RadioButton GroupName="Group2" Name="RadioButton4"


Margin="15,85,0,0" Height="22" HorizontalAlignment="Left"
VerticalAlignment="Top" Width="76">Button 4
</RadioButton>
110 WPF, Just Code It!

Anda juga dapat menciptakan grup-grup radio button dengan membungkusnya didalam
kontainer, seperti didalam kode berikut:

<StackPanel Height="29" VerticalAlignment="Top">


<RadioButton Name="RadioButton1">Button 1</RadioButton>
<RadioButton Name="RadioButton2">Button 2</RadioButton>
</StackPanel>

<StackPanel Height="34" Margin="0,34,0,0" VerticalAlignment="Top">


<RadioButton Name="RadioButton3">Button 3</RadioButton>
<RadioButton Name="RadioButton4">Button 4</RadioButton>
</StackPanel>

5.5 Kontrol TextBlock

TextBlock adalah salah satu elemen WPF yang paling sederhana. Ia hanya
merepresentasikan sebuah area teks yang muncul didalam sebuah jendela. Contoh
berikut mendemonstrasikan sebuah kontrol TextBlock:

<TextBlock>Here is some text</TextBlock>

Jika Anda ingin mengubah teks didalam TextBlock didalam kode, Anda harus
menetapkan properti Name dari TextBlock sehingga Anda dapat mengacunya didalam
kode, seperti:

<TextBlock Name="TextBlock1">Here is some text</TextBlock>

Kemudian Anda dapat mengubah teks atau properti lainnya dengan mengacunya
didalam kode, seperti:

// C#
TextBlock1.Text = "Here is the changed text";

Kontrol TextBlock menyediakan dukungan teks yang fleksibel untuk aplikasi-aplikasi


WPF. Elemen ini ditargetkan terutama kearah skenario-skenario UI dasar yang tidak
111 WPF, Just Code It!

membutuhkan lebih dari satu paragraf teks. Kontrol ini mendukung sejumlah properti
yang memungkinkan kontrol yang tepat atas presentasi, seperti FontFamily, FontSize,
FontWeight, TextEffect dan TextWrapping. Konten teks dapat ditambahkan
menggunakan properti Text. Ketika digunakan didalam XAML, konten antara tag
pembuka dan tag penutup secara implisit ditambahkan sebagai teks elemen.

Sebuah elemen TextBlock dapat diinstansiasi dengan sangat sederhana menggunakan


XAML.

XAML
<TextBlock FontSize="18" FontWeight="Bold" FontStyle="Italic">
Hello, world!
</TextBlock>

Penggunaan elemen TextBlock didalam kode juga relatif sederhana.


C#
TextBlock myTextBlock = new TextBlock();
myTextBlock.FontSize = 18;
myTextBlock.FontWeight = FontWeights.Bold;
myTextBlock.FontStyle = FontStyles.Italic;
myTextBlock.Text = "Hello, world!";

Contoh berikut memperlihatkan bagaimana cara menggunakan elemen TextBlock.


C#
<TextBlock Name="textBlock1" TextWrapping="Wrap">
<Bold>TextBlock</Bold> is designed to be
<Italic>lightweight</Italic>,
and is geared specifically at integrating <Italic>small</Italic>
portions of flow content into a UI.
</TextBlock>

<Button Width="100" Margin="10">Click Me</Button>

<TextBlock Name="textBlock2"
TextWrapping="Wrap" Background="AntiqueWhite" TextAlignment="Center"
112 WPF, Just Code It!

>
By default, a TextBlock provides no UI beyond simply displaying its
contents.
</TextBlock>

<Button Width="100" Margin="10">Click Me</Button>

Hasilnya adalah:

Gambar 5.5 Contoh penggunaan elemen TextBlock

Contoh berikut memperlihatkan bagaimana cara mendapatkan hasil seperti gambar 5.5
secara programatik.

C#
TextBlock textBlock1 = new TextBlock();
TextBlock textBlock2 = new TextBlock();

textBlock1.TextWrapping = textBlock2.TextWrapping = TextWrapping.Wrap;


textBlock2.Background = Brushes.AntiqueWhite;
textBlock2.TextAlignment = TextAlignment.Center;

textBlock1.Inlines.Add(new Bold(new Run("TextBlock")));


textBlock1.Inlines.Add(new Run(" is designed to be "));
textBlock1.Inlines.Add(new Italic(new Run("lightweight")));
textBlock1.Inlines.Add(new Run(", and is geared specifically at
integrating "));
textBlock1.Inlines.Add(new Italic(new Run("small")));
textBlock1.Inlines.Add(new Run(" portions of flow content into a
UI."));
113 WPF, Just Code It!

textBlock2.Text = "By default, a TextBlock provides no UI beyond simply


displaying its contents.";

5.6 Kontrol Image

Elemen Image digunakan untuk menampilkan gambar-gambar bitmap didalam aplikasi


WPF. Kelas Image memungkinkan Anda untuk memuat tipe-tipe image berikut: .bmp,
.gif, .ico, .jpg, .png, .wdp, dan .tiff.

Properti utama dari kontrol Image adalah properti Source. Properti ini mengambil
sebuah kelas System.Windows.Media.ImageSource didalam kode, namun ketika
ditetapkan didalam XAML ia dapat ditetapkan sebagai Uniform Resource Identifier (URI)
dimana image dimuat. Sebagai contoh, lihat kode berikut:

<Image Source="C:\Pictures\Cherry.jpg"/>

URI bisa berupa local disk resource atau Web resource. Properti Image.Stretch
menentukan bagaimana sebuah image ditampilkan, apakah ditampilkan pada ukuran
sebenarnya dan dipotong (jika perlu) agar sesuai dengan batas image, atau apakah
ditampilkan dengan diperkecil atau diperbesar agar sesuai dengan batas kontrol Image.
Nilai-nilai yang mungkin untuk properti Stretch:

 None: Konten image dipresentasikan pada ukuran aslinya. Jika perlu, ia dipotong
agar sesuai dengan ruang yang tersedia.
 Fill: Konten image disesuaikan ukurannya (diperbesar atau diperkecil sesuai
kebutuhan) agar sesuai dengan ukuran kontrol Image.
 Uniform: Konten image disesuaikan ukurannya agar sesuai dengan dimensi
tujuan sembari mempertahankan aspek rasio aslinya. Tidak akan terjadi
pemotongan, sehingga mungkin terdapat ruang kosong pada tepi kontrol Image.
 UniformToFill: Konten image disesuaikan ukurannya agar sesuai dengan dimensi
tujuan sembari mempertahankan aspek rasio aslinya. Jika aspek rasio dari
114 WPF, Just Code It!

kontrol Image berbeda dari konten image, konten tersebut dipotong agar sesuai
dengan kontrol Image.

Ketika menampilkan sebuah image yang multiframe, hanya frame pertama yang
ditampilkan. Animasi atas image multiframe tidak didukung oleh kontrol Image.

Hingga konten image dimuat, ActualWidth dan ActualHeight dari kontrol akan
dilaporkan sebagai nol, karena konten image digunakan untuk menentukan lokasi dan
ukuran final kontrol.

5.7 Kontrol TextBox

Kelas TextBox memungkinkan Anda untuk menampilkan atau mengubah teks tak
berformat. Kegunaan umum dari TextBox adalah mengubah teks tak berformat didalam
sebuah form. Sebagai contoh, form yang meminta nama, nomor telepon, dll akan
menggunakan kontrol TextBox untuk masukan teks.

Kontrol Textbox mengizinkan pengguna untuk menuliskan teks kedalam UI. Teks
tersebut dapat diakses kemudian oleh aplikasi didalam properti TextBox.Text. Anda
dapat menggunakan sebuah TextBox semata-mata untuk tampilan teks dengan
mengatur properti IsReadOnly menjadi True, seperti:

<TextBox IsReadOnly="True" Height="93" Margin="16,14,97,0"


Name="TextBox1" VerticalAlignment="Top"/>

Kode sebelumnya menonaktifkan masukan pengguna untuk kontrol TextBox1.

Walaupun kontrol TextBox dapat diciptakan sebagai sebuah rectangle, secara default ia
berbaris tunggal. Untuk memungkinkan pembungkusan teks didalam sebuah TextBox,
tetapkan properti TextWrapping menjadiWrap, seperti:

<TextBox TextWrapping="Wrap" Height="93" Margin="16,14,97,0"


Name="TextBox1" VerticalAlignment="Top"/>
115 WPF, Just Code It!

Menetapkan properti TextWrapping menjadi Wrap menyebabkan teks dibungkus ke


baris baru ketika tepi kontrol TextBox dicapai, secara otomatis memperbesar kontrol
TextBox untuk baris baru.

Anda juga dapat menetapkan properti TextWrapping menjadi WrapWithOverflow, yang


mengizinkan beberapa kata untuk menerjang tepi text box jika algoritma pembungkusan
tidak mampu memecah teks dalam lokasi yang sesuai.

Kontrol TextBox mencakup dukungan otomatis untuk scroll bars. Anda dapat
mengaktifkan vertical scroll bars dengan menetapkan properti VerticalScrollBarVisibility
menjadi Auto atau Visible, seperti:

<TextBox VerticalScrollBarVisibility="Visible" Height="93"


Margin="16,14,97,0" Name="TextBox1" VerticalAlignment="Top"/>

Menetapkan VerticalScrollBarVisibility menjadi Visible akan membuat vertical scroll bar


terlihat terus-menerus, sementara menetapkannya menjadi Auto akan membuat
vertical scroll bar tampil hanya ketika terdapat konten yang dapat di-skrol. Anda juga
dapat mengaktifkan horizontal scroll bar dengan menetapkan properti
HorizontalScrollBar, namun hal ini tidak begitu berguna.

TextBox atau RichTextBox?

Baik TextBox maupun RichTextBox mengizinkan pengguna untuk memasukkan teks


namun kedua kontrol ini digunakan untuk skenario yang berbeda. Sebuah TextBox
membutuhkan sumber daya sistem yang lebih sedikit daripada sebuah RichTextBox
sehingga TextBox ideal ketika hanya plain text yang perlu diedit. RichTextBox adalah
pilihan yang lebih baik ketika dibutuhkan untuk mengubah teks berformat, gambar,
tabel, atau konten lain yang didukung. Sebagai contoh, mengubah sebuah dokumen,
artikel, atau blog yang membutuhkan pengaturan format, gambar, dll lebih cocok
menggunakan sebuah RichTextBox.
116 WPF, Just Code It!

5.8 Kontrol ComboBox

Kontrol ComboBox mempresentasikan sebuah daftar opsi bagi pengguna. Dalam


keadaan defaultnya, daftar tersebut hanya menampilkan satu pilihan saja. Pengguna klik
button untuk melihat daftar opsi yang lengkap.

Gambar 5.6 ComboBox dalam keadaan collapsed dan expanded

ComboBox mengizinkan pengguna untuk memilih sebuah item dari drop-down list atau
secara opsional memasukkan teks baru didalam text box kontrol.

Properti IsEditable dan IsReadOnly menentukan bagaimana ComboBox berperilaku


ketika pengguna melakukan salah satu hal berikut:

 Memasukkan sebuah string string untuk memilih sebuah item didalam


ComboBox.

 Memasukkan sebuah string string yang tidak terkait dengan sebuah item didalam
ComboBox.

 Memilih bagian dari string yang ada didalam text box.

 Menyalin atau menempelkan sebuah nilai kedalam text box.

Kontrol ComboBox sangat mirip dengan kontrol ListBox. Ia dapat memuat sebuah daftar
item, yang masing-masing dapat berupa sebuah obyek dengan tipe apapun, seperti
didalam kontrol ListBox. Sehingga, kontrol ComboBox dapat menampung sebuah daftar
117 WPF, Just Code It!

string, sebuah daftar kontrol seperti CheckBoxes, atau daftar jenis apapun. Perbedaan
antara kontrol ComboBox dan kontrol ListBox adalah bagaimana kontrol
dipresentasikan. Kontrol ComboBox tampil sebagai sebuah drop-down list. Seperti
kontrol ListBox, Anda bisa mendapatkan acuan ke item yang dipilih melalui properti
SelectedItem dan Anda dapat mengambil indeks dari item yang dipilih melalui properti
SelectedIndex.

Ketika sebuah item dipilih, representasi string dari konten item tersebut ditampilkan
didalam kontrol ComboBox. Sehingga, jika kontrol ComboBox menampung sebuah
daftar string, maka string yang dipilih akan ditampilkan. Jika kontrol ComboBox
menampung sebuah daftar kontrol CheckBox, representasi string dari properti
ComboBox.Content akan ditampilkan. Kemudian nilai yang dipilih akan tersedia melalui
properti ComboBox.Text.

Pengguna juga dapat mengedit teks yang ditampilkan didalam kontrol ComboBox.
Mereka bahkan dapat mengetikkan teks mereka sendiri, seperti didalam sebuah
textbox. Untuk membuat kontrol ComboBox dapat diedit, Anda harus menetapkan
properti IsReadOnly menjadi False dan menetapkan properti IsEditable menjadi True.
Anda dapat membuka dan menutup kontrol ComboBox secara programatik dengan
menetapkan properti IsDrop-DownOpen menjadi True (untuk membukanya) dan False
(untuk menutupnya).

5.9 Kontrol ListBox

Sebuah kontrol ListBox menyediakan sebuah daftar item yang dapat dipilih oleh
pengguna.
118 WPF, Just Code It!

Gambar 5.7 ListBox

Sebuah kontrol ListBox biasanya menampilkan sebuah daftar kontrol ListBoxItem. Cara
paling sederhana untuk mengisi kontrol ListBox adalah dengan menambahkan item-item
secara langsung didalam XAML, seperti:

<ListBox Margin="19,0,0,36" Name="listBox1">


<ListBoxItem>This</ListBoxItem>
<ListBoxItem>Is</ListBoxItem>
<ListBoxItem>A</ListBoxItem>
<ListBoxItem>List</ListBoxItem>
</ListBox>

ListBox adalah sebuah kontrol yang memuat sekumpulan item. Lebih dari satu item
didalam sebuah ListBox yang dapat dilihat, tidak seperti ComboBox, yang mana hanya
item yang dipilih yang dapat dilihat kecuali properti IsDropDownOpen bernilai true.

Secara default, kontrol ListBox mengizinkan Anda untuk memilih sebuah item tunggal.
Anda dapat mengambil indeks dari item yang dipilih dari properti ListBox.SelectedIndex
atau Anda dapat mengambil item yang dipilih tersebut melalui properti
ListBox.SelectedItem. Kontrol ListBoxItem juga mengekspos sebuah properti IsSelected
yang positif ketika item dipilih. Properti SelectionMode menentukan apakah lebih dari
satu item didalam ListBox dapat dipilih pada satu waktu. Nilai yang mungkin untuk
properti ini adalah:

 Single: Pengguna dapat memilih hanya satu item pada satu waktu.
 Multiple: Pengguna dapat memilih banyak item tanpa menahan kunci modifier.
119 WPF, Just Code It!

 Extended: Pengguna dapat memilih banyak item berurutan sembari menahan


kunci Shift atau item tak berurutan dengan menahan kunci Ctrl dan klik item-
item yang diinginkan.

Anda dapat menetapkan properti SelectionMode didalam XAML seperti:

<ListBox SelectionMode="Extended">
</ListBox>

Ketika dipilih banyak item, Anda bisa mendapatkan item-item yang dipilih tersebut
melalui properti ListBox.SelectedItems.

Walaupun kontrol ListBox umumnya digunakan dengan kontrol ListBoxItem, ia dapat


menampilkan sebuah daftar dengan tipe apapun. Sebagai contoh, Anda mungkin ingin
menciptakan sebuah daftar kontrol CheckBox. Anda dapat melakukannya dengan
menambahkan kontrol CheckBox ke kontrol ListBox, seperti:

<ListBox Name="listbox1" VerticalAlignment="Top">


<CheckBox Name="Chk1">Option 1</CheckBox>
<CheckBox Name="Chk2">Option 2</CheckBox>
<CheckBox Name="Chk3">Option 3</CheckBox>
<CheckBox Name="Chk4">Option 4</CheckBox>
</ListBox>

5.10 Kontrol TreeView

Kontrol TreeView menyediakan cara untuk menampilkan informasi di dalam sebuah


struktur hirarkis dengan menggunakan node-node yang dapat diurai dan diringkas.
Dalam implementasinya, TreeView mirip dengan ListBox, namun secara praktis TreeView
sedikit berbeda. Tujuan utama dari kontrol TreeView adalah untuk menampung kontrol
TreeViewItem, yang mengizinkan konstruksi pohon konten.

Kontrol TreeView memuat sebuah hirarki dari kontrol TreeViewItem. Kontrol TreeView
adalah sebuah HeaderedItemsControl yang memiliki sebuah Header dan sebuah koleksi
120 WPF, Just Code It!

Items. Jika Anda menggambarkan sebuah TreeView menggunakan XAML, Anda dapat
secara eksplisit menggambarkan konten Header dari kontrol TreeViewItem dan item-
item yang menyusun koleksinya.

Berikut adalah contoh untuk menciptakan sebuah TreeView:

<TreeView Name="myTreeViewEvent" >


<TreeViewItem Header="Employee1" IsSelected="True">
<TreeViewItem Header="Jesper Aaberg"/>
<TreeViewItem Header="Employee Number">
<TreeViewItem Header="12345"/>
</TreeViewItem>
<TreeViewItem Header="Work Days">
<TreeViewItem Header="Monday"/>
<TreeViewItem Header="Tuesday"/>
<TreeViewItem Header="Thursday"/>
</TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="Employee2">
<TreeViewItem Header="Dominik Paiha"/>
<TreeViewItem Header="Employee Number">
<TreeViewItem Header="98765"/>
</TreeViewItem>
<TreeViewItem Header="Work Days">
<TreeViewItem Header="Tuesday"/>
<TreeViewItem Header="Wednesday"/>
<TreeViewItem Header="Friday"/>
</TreeViewItem>
</TreeViewItem>
</TreeView>

Ketika seorang pengguna mengklik sebuah kontrol TreeViewItem untuk memilihnya,


event Selected terjadi, dan properti IsSelected ditetapkan menjadi true. TreeViewItem
juga menjadi SelectedItem dari kontrol TreeView. Sebaliknya, ketika pilihan berubah dari
sebuah kontrol TreeViewItem, event Unselected terjadi dan properti IsSelected
ditetapkan menjadi false.
121 WPF, Just Code It!

Properti SelectedItem pada kontrol TreeView adalah properti yang read-only, sehingga
Anda tidak dapat menetapkannya secara eksplisit. Properti SelectedItem ditetapkan jika
pengguna klik pada sebuah kontrol TreeViewItem atau ketika properti IsSelected
ditetapkan menjadi true pada kontrol TreeViewItem.

5.11 Menu

Menu memungkinkan Anda untuk mengorganisasi elemen-elemen yang terkait dengan


commands dan event handlers dalam sebuah urutan yang hirarkis. Menu biasanya
dikelompokkan kedalam area-area yang berkaitan. WPF menyediakan dua tipe kontrol
menu, yaitu:

1. Menu, yang dirancang untuk dapat dilihat didalam UI.


2. ContextMenu, yang dirancang untuk berfungsi sebagai sebuah menu pop-up
didalam situasi-situasi tertentu.

5.11.1 Kontrol MenuItem

Keyboard shortcuts adalah kombinasi karakter yang dapat dimasukkan dengan keyboard
untuk membangkitkan perintah-perintah Menu. Sebagai contoh, shortcut untuk Copy
adalah CTRL+C. Adal dua properti yang digunakan dengan keyboard shortcuts dan item-
item menu, yaitu InputGestureText dan Command.

Contoh berikut memperlihatkan bagaimana cara menggunakan properti


InputGestureText untuk memasukkan teks keyboard shortcut ke kontrol MenuItem.
Tinggal menaruh keyboard shortcut didalam item menu, dan tidak mengaitkan perintah
dengan MenuItem. Aplikasi harus menangani masukan pengguna untuk menyelesaikan
aksi.

<MenuItem Header="_Cut" InputGestureText="Ctrl+X"/>


122 WPF, Just Code It!

<MenuItem Header="_Find" InputGestureText="Ctrl+F"/>

Contoh berikut memperlihatkan bagaimana cara menggunakan properti Command


untuk mengaitkan perintah Open dan Save dengan kontrol MenuItem. Properti
Command tidak hanya mengasosiasikan sebuah perintah dengan MenuItem, tapi juga
memasukkan InputGestureText untuk digunakan sebagai shortcut.

<MenuItem Header="_Open" Command="ApplicationCommands.Open"/>


<MenuItem Header="_Save" Command="ApplicationCommands.Save"/>

Berikut adalah beberapa properti penting yang dimiliki oleh kontrol MenuItem:

 Command: Perintah yang diasosiasikan dengan menu item. Perintah ini


dibangkitkan ketika menu item diklik. Jika sebuah keyboard shortcut
diasosiasikan dengan perintah tersebut, ia ditampilkan disebelah kanan menu
item.
 Header: Teks yang ditampilkan didalam menu.
 Icon: Icon yang ditampilkan disebelah kiri menu item. Jika IsChecked ditetapkan
menjadi True, icon tidak ditampilkan bahkan jika sudah ditetapkan.
 IsChecked: Ketika properti ini bernilai True, sebuah tanda cek akan ditampilkan
disebelah kiri menu item. Jika properti Icon ditetapkan, icon tidak ditampilkan
jika IsChecked bernilai True.
 IsEnabled: Menentukan apakah menu item diaktifkan. Ketika False, item tampil
samar dan tidak menjalankan perintah ketika diklik.
 Items: Daftar item yang dimuat oleh kontrol MenuItem. Daftar ini biasanya
memuat lebih banyak kontrol MenuItem.

XAML berikut mendemonstrasikan sebuah menu sederhana:

<Menu Height="22" Name="menu1" VerticalAlignment="Top"


HorizontalAlignment="Left" Width="278">
<MenuItem Header="_File">
<MenuItem Header="Open"/>
123 WPF, Just Code It!

<MenuItem Header="Close"/>
<MenuItem Header="Save" Command="ApplicationCommands.Save"/>
</MenuItem>
</Menu>

5.11.2 Kontrol ContextMenu

ContextMenu merepresentasikan elemen yang mengekspos fungsionalitas dengan


menggunakan sebuah context-specific Menu. Biasanya, pengguna mengekspos
ContextMenu didalam UI dengan klik kanan mouse. Klik sebuah MenuItem akan
membuka sebuah submenu atau mengakibatkan aplikasi melaksanakan perintah.

Kontrol ContextMenu tidak memiliki lokasi tetap didalam UI, melainkan dikaitkan
dengan kontrol lain. Untuk menciptakan sebuah ContextMenu untuk sebuah kontrol,
Anda menggambarkannya didalam kode XAML untuk properti Control.ContextMenu,
seperti diperlihatkan didalam contoh berikut dengan sebuah kontrol ListBox:

<ListBox Margin="77,123,81,39" Name="listBox1">


<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Cut" Command="ApplicationCommands.Cut"/>
<MenuItem Header="Copy" Command="ApplicationCommands.Copy"/>
<MenuItem Header="Paste" Command="ApplicationCommands.Paste"/>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>

Sekali sebuah kontrol ContextMenu telah ditetapkan untuk sebuah kontrol, ia akan
ditampilkan kapanpun pengguna klik kanan kontrol tersebut atau menekan Shift+F10
ketika kontrol mendapatkan fokus. Skenario umum lainnya untuk menambahkan
ContextMenus ke sebuah kontrol adalah menambahkannya ke sebuah resource didalam
Window.Resources collection.
124 WPF, Just Code It!

5.12 Toolbar

Kontrol ToolBar adalah kontainer untuk sekelompok perintah atau kontrol yang
biasanya terkait dalam fungsi mereka. Sebuah ToolBar biasanya memuat tombol-tombol
yang membangkitkan perintah-perintah. Kontrol ToolBar cocok untuk menampung
kontrol-kontrol seperti Button, ComboBox, TextBox, Check-Box dan RadioButton.

Anda menambahkan item-item ke kontrol ToolBar dengan cara yang sama dengan
kontrol item lainnya. Contoh:

<ToolBar Height="26" Margin="43,23,35,0" Name="toolBar1"


VerticalAlignment="Top">
<Button>Back</Button>
<Button>Forward</Button>
<TextBox Name="textbox1" Width="100"/>
</ToolBar>

Ketika lebih banyak kontrol ditambahkan ke sebuah ToolBar daripada jumlah yang dapat
ditampungnya, kontrol-kontrol tersebut akan disingkirkan hingga bersesuaian dengan
ruang yang ada. Kontrol-kontrol yang disingkirkan dari ToolBar secara otomatis
diletakkan didalam menu Overflow.

Gambar 5.8 Toolbar dengan Item Overflow

Menu Overflow muncul sebagai sebuah drop-down list pada sisi kanan toolbar ketika
toolbar ada didalam konfigurasi horizontal. Anda dapat mengelola bagaimana kontrol-
kontrol tersebut diletakkan didalam menu Overflow dengan menetapkan properti
ToolBar.OverflowMode. Nilai-nilai yang mungkin untuk properti ini:
125 WPF, Just Code It!

 OverflowMode.Always: Kontrol akan selalu muncul didalam menu Overflow,


bahkan jika ada ruang yang tersedia didalam toolbar.
 OverflowMode.AsNeeded: Kontrol akan dipindahkan ke menu Overflow jika
perlu. Ini adalah pengaturan default untuk properti ini.
 OverflowMode.Never: Kontrol dengan nilai ini tidak akan pernah diletakkan
didalam menu Overflow. Jika ada lebih banyak kontrol dengan properti
Toolbar.OverflowMode ditetapkan menjadi Never daripada yang dapat
ditampilkan didalam ruang yang dialokasikan ke toolbar, beberapa kontrol akan
dipotong dan tidak tersedia bagi pengguna.

Contoh berikut mendemonstrasikan bagaimana cara menetapkan properti


Toolbar.OverflowMode:

<ToolBar Height="26" Margin="43,23,35,0" Name="toolBar1"


VerticalAlignment="Top">
<Button ToolBar.OverflowMode="Always">Back</Button>
</ToolBar>

5.13 Kesimpulan

Pada bagian ini dikemukakan berbagai kontrol antarmuka yang dapat digunakan sebagai
sarana komunikasi antarmuka pengembang dan pengguna. Berbagai kontrol yang
mungkin sudah menjadi tampilan kontrol mendasar dikaitkan dengan xaml agar dapat
dideklarasikan secara deklaratif. Hal yang menarik lainnya semua kontrol antarmuka
yang dikemukakan adalah antarmuka berbasis obyek dasar WPF atau dengan kata lain
dapat ditransformasikan dan dimanipulasi seperti halnya shape.
126 WPF, Just Code It!

6 WPF Data Binding

WPF data binding menyediakan sebuah cara yang sederhana dan konsisten bagi aplikasi
untuk menyajikan dan berinteraksi dengan data. Elemen dapat diikatkan ke data dari
berbagai sumber data dalam bentuk obyek CLR (common language runtime) dan XML.

6.1 Data Binding

Data Binding (pengikatan data) adalah proses yang membangun sebuah koneksi antara
UI aplikasi dan logika bisnis. Jika binding memiliki pengaturan yang benar dan data
memberikan notifikasi yang sesuai, maka ketika data mengubah nilainya, elemen-
elemen yang diikatkan ke data tersebut secara otomatis merefleksikan perubahan-
perubahan yang terjadi. Binding juga dapat berarti bahwa jika sebuah representasi luar
data didalam sebuah elemen berubah, maka data dasar dapat secara otomatis diupdate
untuk merefleksikan perubahan tersebut. Sebagai contoh, jika pengguna mengedit nilai
didalam sebuah elemen TextBox, nilai data dasar secara otomatis diupdate untuk
merefleksikan perubahan tersebut.

Kegunaan khusus dari data binding adalah untuk menempatkan data konfigurasi lokal
atau server kedalam form atau kontrol UI lainnya. Pada teknologi WPF, konsep ini
diperluas untuk mencakup pengikatan berbagai properti ke berbagai sumber data.
Didalam WPF, properti dependency elemen dapat diikatkan ke obyek-obyek CLR
(termasuk obyek-obyek ADO.NET atau obyek-obyek yang terkait dengan Web Services
dan Web properties) dan data XML.

Tanpa mempedulikan eleman apa yang Anda ikat dan sifat dari sumber data Anda,
setiap pengikatan data selalu mengikuti model yang diilustrasikan oleh gambar berikut:
127 WPF, Just Code It!

Gambar 6.1 Ilustrasi Data Binding

Seperti yang diilustrasikan oleh gambar 6.1, data binding pada dasarnya adalah
jembatan antara binding target (target pengikatan) dan binding source (sumber
pengikatan). Gambar tersebut mendemonstrasikan konsep dasar pengikatan data WPF:

 Biasanya setiap pengikatan memiliki empat komponen, yaitu sebuah obyek


binding target, sebuah target property, sebuah binding source, dan sebuah path
ke nilai didalam sumber pengikatan untuk digunakan.

 Properti target haruslah sebuah properti khusus yang dikenal dengan property
dependency. Sebagian besar properti UIElement adalah properti dependency
dan sebagian besar properti dependency, kecuali yang read-only, secara default
mendukung pengikatan data.

 Obyek binding source tidak harus menjadi obyek CLR khusus. WPF data binding
mendukung data dalam bentuk obyek CLR dan XML.

Ketika Anda melakukan pengikatan data, Anda mengikatkan binding target ke binding
source. Sebagai contoh, jika Anda menampilkan beberapa data XML dasar didalam
sebuah ListBox menggunakan data binding, Anda mengikatkan ListBox Anda ke data
XML.

6.1.1 Menciptakan sebuah Binding


128 WPF, Just Code It!

Pola penciptaan sebuah pengikatan data, dapat menggunakan obyek Binding. Pada
contoh berikut, obyek binding source adalah sebuah kelas yang bernama MyData dan
didefinisikan didalam namespace SDKSample. Kelas MyData memiliki sebuah properti
string yang bernama ColorName, yang nilainya diset menjadi "Red". Contoh ini
menghasilkan sebuah tombol dengan background berwarna merah.

C#
<DockPanel
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:SDKSample">
<DockPanel.Resources>
<c:MyData x:Key="myDataSource"/>
</DockPanel.Resources>
<DockPanel.DataContext>
<Binding Source="{StaticResource myDataSource}"/>
</DockPanel.DataContext>
<Button Background="{Binding Path=ColorName}"
Width="150" Height="30">Saya di ikat berwarna merah!</Button>
</DockPanel>

Gambar 6.2 menggambarkan diagram dasar dari contoh diatas. Ini adalah sebuah
OneWay binding karena properti Background mendukung OneWay binding secara
default.

Gambar 6.2 OneWay binding


129 WPF, Just Code It!

Menetapkan Binding Source

Ada beberapa cara untuk menentukan obyek binding source. Menggunakan properti
DataContext pada sebuah elemen induk sangat berguna ketika Anda mengikatkan
banyak properti ke sumber yang sama. Meskipun demikian, kadangkala lebih sesuai
untuk menentukan binding source pada deklarasi pengikatan individual. Dari contoh
sebelumnya, dengan tidak menggunakan DataContext, Anda dapat menetapkan
properti Source secara langsung pada deklarasi binding dari tombol, seperti berikut:

C#
<DockPanel.Resources>
<c:MyData x:Key="myDataSource"/>
</DockPanel.Resources>
<Button Width="150" Height="30"
Background="{Binding Source={StaticResource myDataSource},
Path=ColorName}">Saya diikat berwarna merah!
</Button>

Selain mengatur properti DataContext pada sebuah elemen secara langsung,


mewariskan nilai DataContext dari moyang (seperti button didalam contoh pertama),
dan secara eksplisit menetapkan binding source dengan menetapkan properti Source
pada Binding (seperti button pada contoh terakhir), Anda juga dapat menggunakan
properti ElementName atau properti RelativeSource untuk menetapkan binding source.
Properti ElementName sangat berguna ketika Anda mengikatkan ke elemen-elemen lain
didalam aplikasi Anda, seperti ketika Anda menggunakan sebuah slider untuk
menyesuaikan lebar dari sebuah tombol. Properti RelativeSource sangat berguna ketika
binding ditentukan didalam sebuah ControlTemplate atau sebuah Style.

Menetapkan Path ke Nilai

Jika binding source Anda adalah sebuah obyek, gunakan properti Path untuk
menetapkan nilai yang akan digunakan untuk pengikatan data Anda. Jika Anda
130 WPF, Just Code It!

mengikatkan ke data XML, gunakan properti XPath untuk menetapkan nilainya. Dalam
beberapa kasus, dapat digunakan properti Path bahkan ketika data Anda adalah XML.
Sebagai contoh, jika Anda ingin mengakses properti Name dari sebuah XmlNode balikan
(sebagai hasil dari queri XPath), Anda harus menggunakan properti Path sebagai
tambahan untuk properti XPath.

Walaupun kita telah menekankan bahwa Path ke nilai yang digunakan adalah salah satu
dari empat komponen penting dari sebuah binding, dalam skenario dimana Anda ingin
mengikatkan ke seluruh obyek, nilai yang digunakan akan sama dengan obyek binding
source. Pada kasus demikian, Anda bisa tidak menetapkan sebuah Path. Perhatikan
contoh berikut:

C#
<ListBox ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="true"/>

Contoh diatas menggunakan sintaks pengikatan kosong: {Binding}. Dalam kasus ini,
ListBox mewarisi DataContext dari elemen DockPanel induk. Ketika path tidak
ditentukan, defaultnya adalah mengikatkan ke seluruh obyek. Dengan kata lain, path
telah dihilangkan karena kita mengikatkan properti ItemSource ke seluruh obyek.

6.1.2 Binding dan BindingExpression

Kelas Binding adalah kelas level tertinggi untuk deklarasi pengikatan data. kelas Binding
menyediakan banyak properti yang mengizinkan Anda untuk menetapkan karakteristik
dari sebuah binding. Kelas yang terkait yaitu BindingExpression, adalah obyek dasar
yang memelihara koneksi antara sumber dan target. Sebuah binding memuat semua
informasi yang dapat digunakan bersama dalam beberapa ekspresi binding expressions.
BindingExpression adalah sebuah instan ekspresi yang tidak dapat digunakan bersama
dan memuat semua instan informasi dari Binding.
131 WPF, Just Code It!

Pada contoh berikut, myDataObject adalah sebuah instan kelas MyData, myBinding
adalah onbyek Binding sumber, dan kelas MyData adalah sebuah kelas yang
didefinisikan yang memuat sebuah properti string yang bernama MyDataProperty.
Contoh berikut mengikatkan konten teks mytext, sebuah instan TextBlock, ke
MyDataProperty.

C#
//make a new source
MyData myDataObject = new MyData(DateTime.Now);
Binding myBinding = new Binding("MyDataProperty");
myBinding.Source = myDataObject;
myText.SetBinding(TextBlock.TextProperty, myBinding);

Anda dapat menggunakan obyek myBinding yang sama untuk menciptakan binding-
binding lainya. Sebagai contoh, Anda dapat menggunakan obyek myBinding untuk
mengikatkan konten teks dari sebuah check box ke MyDataProperty. Pada skenario
tersebut, akan ada dua instan BindingExpression yang berbagi pakai obyek myBinding.

6.1.3 Binding ke Koleksi

Sebuah obyek binding source dapat diperlakukan sebagai sebuah obyek tunggal dimana
properti-propertinya memuat data atau sebagai sebuah koleksi data dari obyek-obyek
polimorfik yang sering dikelompokkan bersama (seperti hasil dari sebuah query basis
data). Melakukan binding ke sebuah koleksi data adalah sebuah skenario yang umum.
Sebagai contoh, skenario umumnya adalah menggunakan sebuah ItemsControl seperti
sebuah ListBox, ListView, atau TreeView untuk menampilkan sebuah koleksi data.

Jika Anda mengikatkan sebuah ItemsControl ke sebuah koleksi, maka diagramnya


adalah:
132 WPF, Just Code It!

Gambar 6.3 Mengikatkan ItemsControl ke sebuah Koleksi

Untuk mengikatkan ItemsControl ke sebuah koleksi, properti ItemsSource adalah


properti yang digunakan. Anda dapat menganggap properti ItemSource sebagai konten
dari ItemsControl.

6.2 Data Template

Data template adalah sekumpulan kode XAML yang menjelaskan bagaimana data yang
diikatkan ditampilkan. Sebuah data template dapat memuat elemen-elemen yang
masing-masing diikatkan ke sebuah properti data, bersama dengan markup tambahan
yang mendeskripsikan layout, warna, dan aspek-aspek lain dari tampilannya. Contoh
berikut mendemonstrasikan sebuah data template sederhana yang menggambarkan
sebuah elemen Label yang diikatkan ke properti ContactName. Properti Foreground,
Background, BorderBrush, dan BorderThickness juga ditetapkan:

<DataTemplate>
<Label Content="{Binding Path=ContactName}" BorderBrush="Black"
Background="Yellow" BorderThickness="3" Foreground="Blue" />
</DataTemplate>

Katika mengikatkan sebuah properti atau list secara langsung ke sebuah kontrol, Anda
dibatasi untuk mengikatkan sebuah properti tunggal. Meskipun demikian, dengan data
template Anda dapat mengikatkan lebih dari satu properti didalam masing-masing item,
dengan demikian menampilkan banyak bit dari data yang terkait bersama-sama.
133 WPF, Just Code It!

Anda dapat menerapkan data templates ke kontrol konten juga. Walaupun sebuah
kontrol konten dapat menampilkan hanya sebuah rekaman tunggal pada satu waktu, ia
dapat menggunakan semua fitur format dari teknologi data template.

Pengaturan Data Template

Anda menetapkan data template pada sebuah kontrol dengan mengatur satu dari dua
properti. Untuk kontrol konten, Anda menetapkan properti ContentTemplate, seperti
yang bercetak tebal berikut:

<Label Height="23" HorizontalAlignment="Left" Margin="56,0,0,91"


Name="label1" VerticalAlignment="Bottom" Width="120">
<Label.ContentTemplate>
<DataTemplate>
<!--Actual data template omitted-->
</DataTemplate>
</Label.ContentTemplate>
</Label>

Untuk kontrol item, Anda menetapkan properti ItemsTemplate, seperti yang bercetak
tebal berikut:

<ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True"


Margin="18,19,205,148" Name="listBox1">
<ListBox.ItemTemplate>
<DataTemplate>
<!--Actual data template omitted-->
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Untuk kontrol item, properti DisplayMemberPath dan ItemTemplate eksklusif satu sama
lain—Anda dapat menetapkan salah satu saja.
134 WPF, Just Code It!

Sebuah pola yang sering muncul dengan data templates adalah mendefinisikannya
didalam sebuah koleksi sumber daya dan mereferensinya didalam elemen Anda. Yang
dibutuhkan untuk menggunakan kembali sebuah data template dalam cara ini adalah
mendefinisikan template tersebut didalam sebuah koleksi sumber daya dan
menetapkan sebuah Key untuk template tersebut, seperti:

<Window.Resources>
<DataTemplate x:Key="myTemplate">
<Label Content="{Binding Path=ContactName}" BorderBrush="Black"
Background="Yellow" BorderThickness="3" Foreground="Blue" />
</DataTemplate>
</Window.Resources>

Kemudian Anda dapat menetapkan template dengan mengacunya ke sumber daya,


seperti yang bercetak tebal berikut:

<ListBox ItemTemplate="{StaticResource myTemplate}"


Name="ListBox1" />

6.3 Validasi Data

Sebagian besar aplikasi yang mengambil masukan pengguna perlu memiliki logika
validasi untuk memastikan bahwa pengguna telah memasukkan informasi yang
diharapkan. Pemeriksaan validasi dapat berdasarkan pada tipe, jangkauan, format, atau
lainnya.

6.3.1 Mengasosiasikan ValidationRules dengan Binding

Model WPF data binding mengizinkan Anda untuk mengasosiasikan ValidationRules


dengan obyek Binding. Contoh:

C#
135 WPF, Just Code It!

<TextBox Name="StartPriceEntryForm" Grid.Row="2" Grid.Column="1"


Style="{StaticResource textStyleTextBox}" Margin="8,5,0,5">
<TextBox.Text>
<Binding Path="StartPrice" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ExceptionValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>

Properti ValidationRules mengambil koleksi dari obyek-obyek ValidationRule.


ExceptionValidationRule adalah sebuah ValidationRule built-in yang memeriksa eksepsi-
eksepsi yang dilemparkan selama update properti binding source. Dalam contoh ini,
properti binding source adalah StartPrice (bertipe integer) dan properti target adalah
Text. Ketika pengguna memasukkan sebuah nilai yang tidak dapat dikonversi ke sebuah
integer, sebuah eksepsi dilemparkan, yang mengakibatkan binding ditandai sebagai
invalid.
Anda juga dapat menciptakan aturan validasi Anda sendiri dengan kelas ValidationRule
dan mengimplementasikan metode Validate. Contoh:

C#
class FutureDateRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo
cultureInfo)
{
DateTime date;
try
{
date = DateTime.Parse(value.ToString());
}
catch (FormatException)
{
return new ValidationResult(false, "Value is not a valid
136 WPF, Just Code It!

date.");
}
if (DateTime.Now.Date > date)
{
return new ValidationResult(false, "Please enter a date in
the future.");
}
else
{
return ValidationResult.ValidResult;
}
}
}

TextBox StartDateEntryForm menggunakan FutureDateRule ini, seperti:


C#
<TextBox Name="StartDateEntryForm" Grid.Row="3" Grid.Column="1"
Validation.ErrorTemplate="{StaticResource validationTemplate}"
Style="{StaticResource textStyleTextBox}" Margin="8,5,0,5">
<TextBox.Text>
<Binding Path="StartDate" UpdateSourceTrigger="PropertyChanged"
Converter="{StaticResource dateConverter}" >
<Binding.ValidationRules>
<src:FutureDateRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>

6.3.2 Menyediakan Umpan Balik Visual

Jika pengguna memasukkan sebuah nilai yang invalid, Anda mungkin ingin memberikan
beberapa umpan balik tentang error pada UI aplikasi. Salah satu cara untuk
menyediakan umpan balik adalah menetapkan properti ErrorTemplate ke sebuah
ControlTemplate khusus. Seperti yang diperlihatkan pada contoh sebelumnya, TextBox
137 WPF, Just Code It!

StartDateEntryForm menggunakan sebuah ErrorTemplate yang disebut


validationTemplate. Contoh berikut memperlihatkan definisi dari validationTemplate:

C#
<ControlTemplate x:Key="validationTemplate">
<DockPanel>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
<AdornedElementPlaceholder/>
</DockPanel>
</ControlTemplate>

Elemen AdornedElementPlaceholder menentukan dimana kontrol yang sedang dihias


harus diletakkan.
Sebagai tambahan, Anda juga dapat menggunakan sebuah ToolTip untuk menampilkan
pesan error. Baik TextBox StartDateEntryForm maupun StartPriceEntryForm
menggunakan style textStyleTextBox, yang menciptakan sebuah ToolTip yang
menampilkan pesan error. Contoh berikut memperlihatkan definisi dari
textStyleTextBox. Properti HasError bernilai true ketika salah satu atau lebih binding
pada properti elemen bound memiliki error.

C#
<Style x:Key="textStyleTextBox" TargetType="TextBox">
<Setter Property="Foreground" Value="#333333" />
<Setter Property="MaxLength" Value="40" />
<Setter Property="Width" Value="392" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
138 WPF, Just Code It!

Dengan ErrorTemplate khusus dan ToolTip, TextBox StartDateEntryForm terlihat seperti


berikut ketika ada sebuah error validasi:

Gambar 6.4 Tampilan ErrorTemplate khusus dan ToolTip untuk sebuah error validasi

Jika Binding Anda memiliki aturan-aturan validasi namun Anda tidak menetapkan
ErrorTemplate pada kontrol pengikatan, ErrorTemplate default akan digunakan untuk
memberitahu pengguna ketika ada sebuah error validasi. ErrorTemplate yang default
adalah sebuah template kontrol yang menggambarkan sebuah border merah. Dengan
ErrorTemplate yang default dan ToolTip, TextBox StartDateEntryForm terlihat seperti
berikut ketika ada sebuah error validasi:

Gambar 6.5 Tampilan ErrorTemplate default dan ToolTip untuk sebuah error validasi

6.4 Kesimpulan

Saat ini tidak ada satu aplikasi bisnis apapun yang tidak melibatkan data. WPF
menyediakan berbagai macam pola pengikatan data yang menekankan pada sisi
interaktifitas dalam pengikatan dan sumber data yang beragam. Pengikatan data ini
dilengkapi dengan validasi data yang bersesuaian dan dapat dikostumisasi sesuai
dengan kebutuhan.
139 WPF, Just Code It!

7 WPF Documents and Printing

WPF menawarkan berbagai fitur dokumen yang memungkinkan penciptaan konten


dengan ketepatan tinggi yang dirancang agar lebih mudah diakses dan dibaca daripada
didalam Windows generasi sebelumnya. Untuk meningkatkan kemampuan dan kualitas,
WPF juga menyediakan layanan terintegrasi untuk tampilan, pengemasan, dan
keamanan dokumen.

7.1 Dokumen
7.1.1 Jenis-jenis Dokumen
7.1.1.1 Fix Document

Fix Document ditujukan untuk aplikasi-aplikasi yang membutuhkan presentasi WYSIWYG


(what you see is what you get) yang tepat, tidak bergantung pada hardware display atau
printer yang digunakan. Penggunaan umum untuk fix document mencakup publikasi
desktop, pemrosesan kata, dan pemformatan layout, dimana ketetapan pada desain
halaman asli adalah hal yang sangat penting.

Sebagai bagian dari layoutnya, sebuah fix document memelihara penempatan posisi
yang tepat atas elemen-elemen konten yang tidak bergantung pada perangkat printer
atau display yang sedang digunakan. Sebagai contoh, sebuah halaman fix document
yang ditampilkan pada display 96 dpi akan tampil persis sama ketika dicetak ke printer
laser 600 dpi seperti ketika dicetak ke phototypesetter 4800 dpi. Layout halaman masih
sama dalam semua kasus, sementara kualitas dokumen dimaksimalkan sesuai
kemampuan masing-masing perangkat.

7.1.1.2 Flow Document

Flow document dirancang untuk mengoptimalkan tampilan dan kemampuan dibaca dan
paling baik digunakan saat kemudahan pembacaan adalah skenario utama konsumsi
140 WPF, Just Code It!

dokumen. Dokumen alir secara dinamis menyesuaikan dan mengalirkan kembali


kontennya berdasarkan pada variabel-variabel run-time seperti ukuran jendela, resolusi
perangkat, dan preferensi pengguna yang opsional.

Halaman Web adalah sebuah contoh sederhana dari sebuah flow document dimana
konten halaman secara dinamis diformat agar sesuai dengan jendela saat ini. Dokumen
alir mengoptimalkan pengalaman tampilan dan pembacaan bagi pengguna, berdasarkan
lingkungan runtime. Sebagai contoh, flow document yang sama akan secara dinamis
diformat ulang untuk kemampuan dibaca yang optimal pada display 19-inch resolusi
tinggi atau sebuah layar PDA 2x3-inch. Sebagai tambahan, flow document memiliki
sejumlah fitur-fitur built in termasuk pencarian, mode tampilan yang mengoptimalkan
kemampuan dibaca, dan kemampuan untuk mengubah ukuran dan tampilan font.

7.1.2 Kontrol-kontrol Dokumen dan Layout Teks

.NET Framework menyediakan seperangkat kontrol bawaan yang menyederhanakan


penggunaan fix document, flow document, dan teks umum didalam aplikasi anda.
Tampilan dari konten fix document didukung menggunakan kontrol DocumentViewer.
Tampilan dari konten flow document didukung oleh tiga kontrol yang berbeda:
FlowDocumentReader, FlowDocumentPageViewer, dan FlowDocumentScrollViewer
yang dipetakan ke skenario-skenario pengguna yang berbeda. Kontrol WPF lainnya
menyediakan layout yang disederhanakan untuk mendukung penggunaan teks umum.

7.1.2.1 Kontrol Fix Document - DocumentViewer

Kontrol DocumnetViewer dirancang untuk menampilkan konten FixedDocument.


Kontrol DocumnetViewer menyediakan sebuah antarmuka yang intuitif yang
menyediakan dukungan built-in untuk operasi-operasi umum termasuk fitur-fitur
mencetak keluaran, menyalin ke clipboard, zoom, dan mencari teks. Kontrol ini
menyediakan akses ke halaman-halaman konten melalui sebauah mekanisme skrol yang
141 WPF, Just Code It!

familiar. Seperti semua kontrol WPF, DocumnetViewer mendukung penetapan gaya


yang lengkap atau parsial, yang memungkinkan kontrol diintegrasikan secara visual
kedalam aplikasi atau lingkungan manapun. DocumnetViewer dirancang untuk
menampilkan konten yang read-only; sehingga tidak mendukung pengubahan atau
modifikasi konten.

7.1.2.2 Kontrol Flow Document

Tampilan konten flow document didukung oleh tiga kontrol: FlowDocumentReader,


FlowDocumentPageViewer dan FlowDocumentScrollViewer.

7.1.2.2.1 FlowDocumentReader

FlowDocumentReader mencakup fitur-fitur yang memungkinkan pengguna untuk secara


dinamis memilih berbagai mode tampilan, termasuk mode tampilan halaman tunggal
(page-at-a-time), mode tampilan two-page-at-a-time (format pembacaan buku), dan
mode tampilan continuous scrolling (tak berdasar). Jika anda tidak membutuhkan
kemampuan untuk berpindah secara dinamik antara mode tampilan yang berbeda,
FlowDocumentPageViewer dan FlowDocumentScrollViewer menyediakan viewer yang
lebih ringan yang ditempatkan dalam mode tampilan tertentu.

7.1.2.2.2 FlowDocumentPageViewer dan FlowDocumentScrollViewer

FlowDocumentPageViewer menampilkan konten didalam mode tampilan page-at-a-


time, sedangkan FlowDocumentScrollViewer menampilkan konten didalam mode
continuous scrolling. Baik FlowDocumentPageViewer maupun
FlowDocumentScrollViewer ditempatkan di mode tampilan tertentu. Dibandingkan
dengan FlowDocumentReader, yang mencakup fitur-fitur yang memungkinkan
pengguna untuk secara dinamis memilih berbagai mode tampilan (seperti yang
142 WPF, Just Code It!

disediakan oleh enumerasi FlowDocumentReaderViewingMode), dampaknya adalah


lebih intensif terhadap sumber daya daripada FlowDocumentPageViewer atau
FlowDocumentScrollViewer.

Secara default, sebuah scrollbar vertikal selalu ditampilkan, dan sebuah scrollbar
horizontal dapat dilihat jika perlu. UI default untuk FlowDocumentScrollViewer tidak
mencakup sebuah toolbar; meskipun demikian properti IsToolBarVisible dapat
digunakan untuk mengaktifkan toolbar built-in.

7.1.2.3 Teks didalam Antarmuka

Disamping menambahkan teks ke dokumen, teks dapat digunakan didalam UI aplikasi


seperti form. WPF mencakup banyak kontrol untuk menggambarkan teks ke layar.
Masing-masing kontrol ditargetkan untuk skenario yang berbeda dan memiliki list fitur
dan batasannya sendiri. Secara umum, elemen TextBlock seharusnya digunakan ketika
dibutuhkan dukungan teks terbatas, seperti kalimat ringkas didalam sebuah UI. Label
dapat digunakan ketika dibutuhkan dukungan teks minimal.

7.1.3 Document Packaging

API System.IO.Packaging menyediakan fitur-fitur yang efisien untuk mengorganisasi data


aplikasi, konten dokumen, dan sumber daya terkait didalam sebuah kontainer tunggal
yang mudah diakses, portable, dan mudah disebarkan. Berkas ZIP adalah sebuah contoh
jenis Package yang mampu menampung banyak obyek sebagai sebuah unit tunggal,
packaging API ini menyediakan sebuah implementasi ZipPackage default yang dirancang
menggunakan sebuah Open Packaging Conventions standard dengan arsitektur XML dan
ZIP. WPF packaging APIs menyederhanakan penciptaan package, dan untuk menyimpan
dan mengakses obyek-obyek didalamnya. Sebuah obyek yang disimpan didalam sebuah
Package diacu sebagai sebuah PackagePart. Packages juga dapat mencakup sertifikat
143 WPF, Just Code It!

digital sah yang dapat digunakan untuk mengidentifikasi keaslian dari sebuah bagian
dan untuk memvalidasi bahwa konten dari sebuah package belum dimodifikasi.
Packages juga mencakup fitur PackageRelationship yang mengijinkan penambahan
informasi tambahan ke sebuah package atau diasosiasikan dengan bagian-bagian
tertentu tanpa memodifikasi konten dari part-part yang ada. Layanan Package juga
mendukung Microsoft Windows Rights Management (RM).

Arsitektur WPF Package menjadi dasar untuk beberapa teknologi kunci:

 Dokumen XPS yang menjadi XML Paper Specification (XPS).

 Microsoft Office "12" open XML format documents (.docx).

 Format penyimpanan khusus untuk desain aplikasi anda.

Berdasarkan pada packaging APIs, XpsDocument secara khusus dirancang untuk


menyimpan dokumen-dokumen konten fix WPF. Sebuah XpsDocument adalah sebuah
self-contained document yang dapat dibuka didalam sebuah viewer, ditampilkan
didalam sebuah kontrol DocumentViewer, dikirimkan ke print spool, atau dikeluarkan
secara langsung ke sebuah XPS-compatible printer.

7.1.3.1 Komponen-komponen Package

WPF packaging APIs mengijinkan dokumen dan data aplikasi untuk diorganisasikan
kedalam sebuah unit portable tunggal. Sebuah berkas ZIP adalah salah satu jenis
package umum dan merupakan jenis package default yang disediakan dengan WPF.
Package sendiri adalah sebuah kelas abstrak dimana ZipPackage diimplementasikan
menggunakan sebuah open standard XML dan arsitektur berkas ZIP. Metode Open
menggunakan ZipPackage untuk menciptakan dan menggunakan berkas-berkas ZIP
secara default. Sebuah package dapat memuat tiga jenis item dasar:

 PackagePart: Konten aplikasi, data, dokumen dan berkas sumber daya.


144 WPF, Just Code It!

 PackageDigitalSignature: X.509 Certificate for identification, authentication and


validation.
 PackageRelationship: Added information related to the package or a specific
part.

7.1.3.1.1 PackageParts

Sebuah PackagePart ("part") adalah sebuah kelas abstrak yang mengacu ke sebuah
obyek yang disimpan didalam sebuah Package. Didalam sebuah berkas ZIP, package
parts berkaitan dengan berkas-berkas individual yang disimpan didalam bekas ZIP.
ZipPackagePart menyediakan impelementasi default untuk obyek-obyek serializable
yang disimpan didalam sebuah ZipPackage. Seperti sebuah sistem berkas, bagian-bagian
yang dimuat didalam package disimpan didalam direktori hirarkis atau organisasi
"folder-style". Dengan menggunakan WPF packaging APIs, aplikasi dapat menulis,
menyimpan dan membaca banyak obyek PackagePart menggunakan sebuah kontainer
berkas ZIP tunggal.

7.1.3.1.2 PackageDigitalSignatures

Untuk keamanan, sebuah PackageDigitalSignature ("digital signature") dapat


diasosiasikan dengan bagian-bagian didalam sebuah package. PackageDigitalSignature
menyertakan sebuah 509 yang menyediakan dua fitur:

1. Mengidentifikasi dan mengautentikasi keaslian dari part.

2. Memvalidasi part tersebut belum dimodifikasi.

Digital signature tidak menghalangi sebuah part untuk dimodifikasi, namun sebuah
pemeriksaan validasi yang melawan digital signature akan gagal jika part tersebut
diubah dengan cara apapun. Kemudian aplikasi dapat mengambil tindakan yang
145 WPF, Just Code It!

sesuai—sebagai contoh, blok yang membuka part atau memberitahu pengguna bahwa
part telah dimodifikasi dan tidak aman.

7.1.3.1.3 PackageRelationships

PackageRelationship ("relationship") menyediakan sebuah mekanisme untuk


mengasosiasikan informasi tambahan dengan package atau sebuah part didalam
package. Relationship adalah sebuah fasilitas level package yang dapat mengasosiasikan
informasi tambahan dengan sebuah part tanpa memodifikasi konten part aktual.
Menyisipkan data baru secara langsung kedalam konten part biasanya tidak praktis
dalam banyak kasus:

 Tipe aktual dari part dan skema kontennya tidak diketahui.

 Bahkan jika diketahui, skema konten mungkin tidak menyediakan fungsi untuk
menambahkan informasi baru.

 Part mungkin secara digital ditandai atau dienkripsi, yang menghalangi


modifikasi apapun.

Package relationships menyediakan fungsi untuk menambahkan dan mengasosiasikan


informasi tambahan dengan part-part individual atau dengan keseluruhan package.
Package relationships digunakan untuk dua fungsi primer:

1. Menggambarkan dependency relationships dari satu part ke part lainnya.

2. Menggambarkan information relationships yang menambahkan catatan atau


data lain yang terkait dengan part tersebut.

PackageRelationship menyediakan sebuah fungsi cepat untuk menggambarkan


dependensi dan menambahkan informasi lain yang terkait dengan sebuah part dari
package atau package sebagai sebuah keseluruhan.
146 WPF, Just Code It!

7.1.3.1.4 Dependency Relationships

Dependency relationships digunakan untuk menjelaskan dependensi yang dibuat oleh


satu part ke part-part lainnya. Sebagai contoh, sebuah package dapat memuat sebuah
bagian HTML yang mencakup satu atau lebih tag image <img>. Image tags mengacu ke
gambar yang diletakkan sebagai bagian internal package ataupun bagian eksternal
package. Menciptakan sebuah PackageRelationship yang diasosiasikan dengan berkas
HTML membuat penemuan dan pengaksesan dependent resources secara cepat dan
mudah. Sebuah aplikasi browser atau viewer dapat secara langsung mengakses part
relationships dan segera memulai merakit sumber dependent resources tanpa
mengetahui skema atau menguraikan dokumen.

7.1.3.1.5 Information Relationships

Sebuah PackageRelationship juga dapat digunakan untuk menyimpan jenis-jenis


informasi lain untuk diasosiasikan dengan sebuah part tanpa harus memodifikasi konten
part tersebut.

7.1.4 Dokumen XPS

Dokumen XML Paper Specification (XPS) adalah sebuah package (pemaketan) yang
memuat satu atau lebih fix document bersama dengan semua sumber daya dan
informasi yang dibutuhkan untuk proses render. XPS juga merupakan format natif
berkas print spool Windows Vista. Sebuah XpsDocument disimpan didalam dataset ZIP
standard, dan dapat mencakup sebuah kombinasi XML dan komponen-komponen biner,
seperti berkas font dan image. PackageRelationships digunakan untuk menggambarkan
dependensi antara konten dan sumber daya yang dibutuhkan untuk merender dokumen
secara penuh. Desain XpsDocument menyediakan sebuah solusi dokumen tunggal
dengan ketepatan tinggi yang mendukung berbagai fungsi:
147 WPF, Just Code It!

 Membaca, menulis, dan menyimpan konten dan sumber daya fix document
sebagai sebuah berkas tunggal, portable dan mudah didistribusikan.

 Menampilkan dokumen-dokumen dengan aplikasi XPS Viewer.

 Mengeluarkan dokumen dalam format natif print spool Windows Vista.

 Mengirimkan dokumen secara langsung ke sebuah XPS-compatible printer.

7.2 Pencetakan

Pencetakan didalam WPF jauh lebih mudah dibandingkan pencetakan didalam Windows
Forms. Untuk sebagian besar dokumen, dukungan pencetakan sudah ada dan tidak
membutuhkan penulisan kode tambahan. Untuk jenis pencetakan lainnya, pencetakan
difasilitasi melalyi metode-metode dari kelas PrintDialog.

7.2.1 Mencetak Dokumen

Semua jenis document views (DocumentViewer, FlowDocumentScrollViewer,


FlowDocumentPageViewer, dan FlowDocumentReader) mendukung pencetakan
dokumen yang mereka muat. Metode Print secara otomatis membuka kotak dialog Print
didalam Microsoft Windows dan mengirimkan dokumen ke printer.

Contoh berikut mendemonstrasikan bagaimana cara mencetak sebuah dokumen yang


termuat didalam viewer apapun:

// C#
aViewer.Print();

Anda juga dapat mencetak sebuah dokumen melalui pertintah


ApplicationCommands.Print. Menjalankan perintah ini dengan sebuah document viewer
yang ditunjuk secara otomatis membuka kotak dialog Print, dimana pengguna dapat
148 WPF, Just Code It!

memilih untuk mengirimkan dokumen ke printer. Anda dapat membangkitkan perintah


ini dari keyboard dengan menekan kombinasi tombol Ctrl+P.

7.2.2 Kelas PrintDialog

Kelas PrintDialog menyediakan dukungan untuk mencetak dokumen dan elemen-


elemen visual. Kelas PrintDialog mengenkapsulasi kotak dialog Print, yang mengijinkan
pengguna untuk memilih sebuah printer dan opsi-opsi yang berkaitan dengan printer
tersebut. Kelas PrintDialog juga mengekspos dua metode untuk memfasilitasi
pencetakan: PrintVisual dan PrintDocument.

Gambar 7.1 Kotak dialog Print

Metode umum untuk mencetak dengan kelas PrintDialog adalah mendeklarasikan


sebuah instan kelas tersebut dan kemudian memanggil metode ShowDialog. Metode ini
mengembalikan sebuah bool?, dan anda harus menguji bahwa metode tersebut
149 WPF, Just Code It!

mengembalikan True (yang mengindikasikan bahwa pengguna klik OK bukan Cancel)


sebelum memanggil metode yang sesuai.

7.2.2.1 Mencetak Elemen-elemen Visual

Metode PrintDialog.PrintVisual dapat digunakan untuk mencetak elemen apapun yang


diturunkan dari kelas Visual, yang memuat semua elemen WPF. Ketika anda mencetak
sebuah elemen WPF, semua elemen anak juga dicetak. Metode PrintVisual mengambil
dua argumen: elemen Visual untuk dicetak dan sebuah deskripsi string dari item yang
sedang dicetak. Contoh berikut mendemonstrasikan metode PrintVisual:

// C#
PrintDialog pd = new PrintDialog();
if (pd.ShowDialog() == true)
{
pd.PrintVisual(this,"The Window");
}

7.2.2.2 Mencetak Dokumen Alir dengan PrintDialog

Sebuah Cara paling mudah untuk mencetak sebuah flow document adalah dengan
memanggil metode Print dari viewer yang memuat dokumen tersebut, atau dengan
membangkitkan perintah Print. Meskipun demikian, anda dapat menggunakan metode
PrintDocument untuk mencetak sebuah flow document secara manual yang ada didalam
memory.

Metode PrintDocument membutuhkan sebuah obyek DocumentPaginator untuk


melakukan pencetakan. Walaupun pendekatan ini sepertinya berputar, anda dapat
memperoleh sebuah object DocumentPaginator yang merepresentasikan flow
document anda dengan melemparkan flow document tersebut sebagai sebuah
IDocumentPaginatorSource dan kemudian mengakses properti DocumentPaginator
150 WPF, Just Code It!

miliknya. Contoh berikut mendemonstrasikan bagaimana cara mencetak sebuah instan


flow document yang bernama myDocument:

// C#
PrintDialog pd = new PrintDialog();
if (pd.ShowDialog() == true)
{
DocumentPaginator aPag;
aPag = ((IDocumentPaginatorSource)myDocument).DocumentPaginator;
pd.PrintDocument(aPag, "My Document");
}

7.3 Kesimpulan

Apabila kita mengingat tentang pemograman ,NET sebelum versi 3.0, maka kita akan
mengingat betapa tingginya kebutuhan kita pada format dokumen pihak ketiga.
Lahirnya spesifikasi dan pustaka dokumen milik WPF, seakan menghadirkan babak baru
dunia pemograman pencetakan dan pengelolaan dokumen yang lebih mudah dan lebih
independen.
151 WPF, Just Code It!

8 WPF Multimedia
8.1 Multimedia

Topik ini memperkenalkan fitur-fitur multimedia dari WPF yang megizinkan Anda untuk
mengintegrasikan suara dan video kedalam aplikasi Anda dalam rangka meningkatkan
pengalaman pengguna.

8.1.1 API Media

Baik MediaElement maupun MediaPlayer digunakan untuk menghadirkan audio, video,


dan video dengan konten audio. Kedua tipe tersebut dapat dikontrol secara interaktif
atau dengan menggunakan clock (jam). Kedua tipe tersebut dapat bersAndar pada
Microsoft Windows Media Player 10 OCX untuk media playback. Meskipun demikian,
penggunaan API ini ditujukan untuk skenario-skenario yang berbeda.

MediaElement adalah sebuah UIElement yang didukung oleh The Layout System dan
dapat digunakan sebagai konten dari banyak kontrol. Ia juga dapat digunakan didalam
XAML seperti halnya kode. Pada sisi lain, MediaPlayer dirancang untuk obyek-obyek
Drawing dan kurang dukungan layout. Media yang dimuat menggunakan MediaPlayer
hanya dapat dihadirkan menggunakan VideoDrawing atau dengan berinteraksi langsung
dengan DrawingContext. MediaPlayer tidak dapat digunakan didalam XAML.

Ketika mendistribusikan media dengan aplikasi Anda, Anda tidak dapat menggunakan
sebuah berkas media sebagai sumber daya proyek. Didalam berkas proyek Anda, Anda
harus menetapkan Media type menjadi Content dan menetapkan
CopyToOutputDirectory menjadi PreserveNewest atau Always.

8.1.2 Mode Playback Media


152 WPF, Just Code It!

Pemahaman konsep playback media didalam WPF, memerlukan pemahaman atas


mode-mode yang berbeda dimana media dapat dimainkan. Baik MediaElement maupun
MediaPlayer dapat digunakan dalam dua mode media yang berbeda, yaitu mode
independent dan mode clock. Mode media ditentukan oleh properti Clock. Ketika Clock
bernilai null, obyek media ada didalam mode independent. Ketika Clock tidak bernilai
null, obyek media ada didalam mode clock. Secara default, obyek-obyek media ada
didalam mode independent.

8.1.2.1 Mode Independent

Pada mode independent, konten media mengakibatkan playback media. Mode


independent memungkinkan opsi-opsi berikut:

 Uri media dapat dispesifikasikan secara langsung.

 Playback media dapat dikontrol secara langsung.

 Properti Position dan SpeedRation milik media dapat dimodifikasi.

Media dapat dimuat dengan menetapkan properti Source milik obyek MediaElement
atau dengan memanggil metode Open milik obyek MediaPlayer.

Untuk mengontrol playback media didalam mode independent, dapat digunakan


metode kontrol milik obyek media. Metode-metode kontrol yang tersedia adalah Play,
Pause, Close, dan Stop. Untuk MediaElement, kontrol interaktif menggunakan metode-
metode ini hanya tersedia ketika LoadedBehavior ditetapkan menjadi Manual. Metode-
metode ini tidak tersedia ketika obyek media ada didalam mode clock.

8.1.2.2 Mode Clock


153 WPF, Just Code It!

Didalam mode clock, MediaTimeline menyebabkan playback media. Mode clock


memiliki karakteristik berikut:

 Uri media ditetapkan secara tak langsung melalui sebuah MediaTimeline.

 Playback media dapat dikontrol oleh Clock. Metode-metode kontrol milik obyek
media tidak dapat digunakan.

 Media dimuat dengan menetapkan sebuah properti Source milik obyek


MediaTimeline, yang menciptakan clock dari timeline, dan memberikan clock
tersebut ke obyek media. Media jga dimuat dengan cara ini ketika
MediaTimeline didalam Storyboard memiliki target MediaElement.

Untuk mengontrol playback media didalam mode clock, metode-metode kontrol


ClockController harus digunakan. ClockController diperoleh dari properti ClockController
dari MediaClock. Jika Anda mencoba menggunakan metode-metode kontrol dari sebuah
obyek MediaElement atau MediaPlayer selama ada didalam mode clock, sebuah
InvalidOperationException akan dilemparkan.

8.1.3 Kelas MediaElement

Menambahkan media ke sebuah aplikasi sama sederhananya dengan menambahkan


sebuah kontrol MediaElement ke UI dari aplikasi dan memberikan sebuah Uri ke media
yang ingin Anda masukan. Semua jenis media yang didukung oleh Microsoft Windows
Media Player 10 didukung didalam WPF. Contoh berikut menampilkan penggunaan
sederhana MediaElement didalam XAML.

C#
<!-- This page shows a simple usage of MediaElement -->
<Page x:Class="MediaElementExample.SimpleUsage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
154 WPF, Just Code It!

Title="SimpleUsage"
>
<StackPanel Margin="20">
<MediaElement Source="media/numbers-aud.wmv" />
</StackPanel>
</Page>

Dalam contoh diatas, media dimainkan secara otomatis sesegera setelah media dimuat.
Setelah media selesai dimainkan, media ditutup dan semua sumber daya media
dilepaskan (termasuk memori video). Ini adalah perilaku default dari obyek
MediaElement dan dikontrol oleh properti LoadedBehavior dan UnloadedBehavior.

8.1.3.1 Mengontrol sebuah MediaElement

Properti LoadedBehavior dan UnloadedBehavior mengontrol perilaku dari


MediaElement ketika IsLoaded berturut-turut bernilai true atau false. Properti
MediaState ditetapkan untuk mempengaruhi perilaku playback media. Sebagai contoh,
niali default LoadedBehavior adalah Play dan nilai default UnloadedBehavior adalah
Close. Ini berarti bahwa setelah MediaElement dimuat dan preroll selesai dilakukan,
media mulai dimainkan. Setelah playback selesai, media ditutup dan semua sumber
daya media dilepaskan.

Properti LoadedBehavior dan UnloadedBehavior bukan satu-satunya cara untuk


mengontrol playback media. Didalam mode clock, clock dapat mengontrol
MediaElement dan metode-metode kontrol interactif memiliki kontrol ketika
LoadedBehavior bernilai Manual. MediaElement menangani kompetisi kontrol ini
dengan mengevaluasi prioritas berikut.

1. UnloadedBehavior.
Ada ketika media tidak dimuat. UnloadedBehavior memastikan bahwa semua
sumber daya media dilepaskan secara default, bahkan ketika sebuah MediaClock
diasosiasikan dengan MediaElement.
155 WPF, Just Code It!

2. MediaClock.
Ada ketika media memiliki sebuah Clock. Jika media tidak dimuat, MediaClock
akan memberikan efek selama UnloadedBehavior bernilai Manual. Mode Clock
selalu mengesampingkan perilaku yang dimuat dari MediaElement.

3. LoadedBehavior.
Ada ketika media dimuat.

4. Metode-metode kontrol interaktif.


Ada ketika LoadedBehavior bernilai Manual. Metode-metode kontrol yang
tersedia adalah Play, Pause, Close, dan Stop.

8.1.3.2 Menampilkan sebuah MediaElement

Untuk menampilkan sebuah MediaElement, ia harus memiliki konten untuk dirender


dan properti ActualWidth dan ActualHeight akan ditetapkan menjadi nol sampai konten
tersebut dimuat. Untuk konten yang hanya audio, properti ini selalu bernilai nol. Untuk
konten video, setelah event MediaOpened dibangkitkan, ActualWidth dan ActualHeight
akan melaporkan ukuran dari media yang dimuat. Ini berarti bahwa hingga media
dimuat, MediaElement tidak akan mengambil ruang fisik didalam UI kecuali properti
Width atau Height ditetapkan.

Dengan menetapkan properti Width dan Height akan menyebabkan media diregangkan
untuk mengisi area yang diberikan untuk MediaElement. Untuk mempertahankan aspek
rasio asli media, properti Width atau Height harus ditetapkan, salah satu saja, tidak
keduanya. Menetapkan properti Width dan Height akan menyebabkan media
dihadirkan dalam ukuran fix yang mungkin tidak diinginkan.

Untuk menghindari elemen berukuran fix, WPF dapat melakukan preroll terhadap
media. Hal ini dapat dilakukan dengan menetapkan LoadedBehavior menjadi Play atau
156 WPF, Just Code It!

Pause. Dalam keadaan Pause, media akan di preroll dan akan memberikan frame
pertama. Dalam keadaan Play, media akan di preroll dan mulai dimainkan.

8.1.4 Kelas MediaPlayer

Kelas MediaPlayer dirancang untuk digunakan didalam obyek-obyek Drawing. Obyek-


obyek Drawing digunakan ketika Anda dapat mengorbankan fitur-fitur level framework
untuk memperoleh keuntungan performa atau ketika Anda membutuhkan fitur-fitur
Freezable. MediaPlayer memungkinkan Anda untuk memanfaatkan fitur-fitur ini
sembari memberikan konten media didalam aplikasi Anda. Seperti MediaElement,
MediaPlayer dapat digunakan didalam mode independent atau clock namun tidak
memiliki keadaan loaded dan unloaded milik obyek MediaElement. Hal ini mengurangi
kompleksitas kontrol playback dari MediaPlayer.

8.1.4.1 Mengontrol MediaPlayer

Hanya ada dua cara untuk mengontrol playback media didalam MediaPlayer.

1. Metode-metode kontrol interaktif. Ada ketika didalam mode independent


(properti Clock null).

2. MediaClock. Ada ketika media memiliki sebuah Clock.

8.1.4.2 Menampilkan MediaPlayer

Secara teknis, sebuah MediaPlayer tidak dapat ditampilkan karena ia tak memiliki
representasi fisik. Meskipun demikian, ia tak dapat digunakan untuk menghadirkan
media didalam sebuah Drawing menggunakan kelas VideoDrawing. Contoh berikut
mendemonstrasikan penggunaan VideoDrawing untuk menampilkan media.
157 WPF, Just Code It!

C#
// Create a VideoDrawing.
MediaPlayer player = new MediaPlayer();
player.Open(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));
VideoDrawing aVideoDrawing = new VideoDrawing();
aVideoDrawing.Rect = new Rect(0, 0, 100, 100);
aVideoDrawing.Player = player;

// Play the video once.


player.Play();

8.2 Animasi

Animasi adalah salah satu fitur baru dari WPF. Animasi megizinkan Anda untuk
mengubah nilai dari sebuah properti setelah melewati suatu periode waktu. Dengan
menggunakan teknik ini, Anda dapat menciptakan berbagai efek visual, termasuk
membuat kontrol membesar atau berpindah didalam UI, mengubah warna secara
berangsur, atau mengubah properti-properti lainnya sepanjang waktu. Menciptakan
sebuah animasi dalam mesin grafis sebelumnya merupakan sebuah proses yang
menghabiskan waktu, namun didalam WPF segalanya lebih sederhana dan Anda dapat
membangun animasi dengan mudah. Animasi merupakan bagian built-in dari XAML
sebagai bahasa markup untuk mendeklarasikan UI didalam WPF dan beberapa opsi
tersedia untuk membangun animasi.

8.2.1 Kelas Animation

Animasi didalam WPF mengacu ke perubahan properti secara otomatis selama periode
waktu tertentu. Anda dapat menganimasikan ukuran, lokasi, warna, atau properti lain
dari sebuah elemen atau properti-properti yang terkait dengan sebuah elemen. Anda
dapat menggunakan kelas Animation untuk mengimplementasikan perubahan-
perubahan ini.
158 WPF, Just Code It!

Kelas Animation adalah sebuah grup besar kelas yang dirancang untuk
mengimplementasikan perubahan properti secara otomatis. Ada 42 kelas Animation
didalam namespace System.Windows.Media.Animation, dan masing-masing memiliki
sebuah tipe data spesifik yang dirancang untuk dianimasikan.

Kelas Animation dibagi menjadi tiga grup dasar, yaitu animasi linier, animasi berbasis
key frame, dan animasi berbasis path.

 Animasi linier, yang mengotomasi perubahan properti dalam sebuah cara yang
linier, diberi nama dalam format <TypeName>Animation, dimana <TypeName>
adalah nama tipe yang sedang dianimasikan. DoubleAnimation adalah sebuah
contoh dari kelas animasi linier, dan merupakan kelas animasi yang paling sering
digunakan.
 Animasi berbasis key frame melakukan animasinya pada basis beberapa titik
jalan, yang disebut key frames. Aliran animasi key-frame dimulai pada bagian
awal, kemudian maju ke setiap key frame sampai ke bagian akhir. Animasi key-
frame diberi nama dalam format <TypeName>AnimationUsingKeyFrames,
dimana <TypeName> adalah nama Type yang sedang dianimasikan. Contohnya
StringAnimationUsingKeyFrames.
 Animasi berbasis path menggunakan sebuah obyek Path untuk memandu
animasi. Animasi ini sering digunakan untuk menganimasikan properti-properi
yang terkait dengan perpindahan obyek-obyek visual sepanjang jalan yang
kompleks. Animasi berbasis path diberi nama dalam format
<TypeName>Animation-UsingPath, dimana <TypeName> adalah nama tipe yang
sedang dianimasikan. Saat ini hanya ada tiga kelas Animation berbasis path, yaitu
PointAnimationUsingPath, Double-AnimationUsingPath, dan
MatrixAnimationUsingPath.

Walaupun ada banyak kelas Animation yang berbeda, mereka semua bekerja dalam cara
fundamental yang sama. Demikian, mereka juga berbagi properti-properti yang umum.
Beberapa properti penting dari kelas Animation adalah sebagai berikut:
159 WPF, Just Code It!

 AccelerationRatio: Mendapatkan atau menetapkan sebuah nilai yang


menetapkan persentase properti Duration dari Animation yang digunakan untuk
mempercepat jalannya waktu dari nol sampai tingkat maksimumnya.
 AutoReverse: Mendapatkan atau menetapkan sebuah nilai yang menAndai
apakah Animation dimainkan secara terbalik setelah ia menyelesaikan iterasi
maju.
 BeginTime: Mendapatkan atau menetapkan waktu dimana Animation harus
mulai, sehubungan dengan waktu dimana Animation dieksekusi. Sebagai contoh,
sebuah Animation dengan BeginTime yang ditetapkan dengan nilai 0:0:5
memberikan penundaan 5 detik sebelum mulai.
 DecelerationRatio: Mendapatkan atau menetapkan sebuah nilai yang
menetapkan persentase durasi Animation yang dihabiskan untuk memperlambat
jalannya waktu dari tingkat maksimum
decelerating the passage of time from its maximum rate to zero.
 Duration: Mendapatkan atau menetapkan lamanya waktu untuk memainkan
Animation.
 FillBehavior: Mendapatkan atau menetapkan sebuah nilai yang menAndai
bagaimana Animation berperilaku setelah selesai.
 RepeatBehavior: Mendapatkan atau menetapkan sebuah nilai yang menAndai
bagaimana Animation berulang.
 SpeedRatio: Mendapatkan atau menetapkan tingkat dimana Animation
berprogres sehubungan dengan induknya.

Sebagai tambahan, kelas animasi linier biasanya mengimplementasikan sedikit lebih


banyak properti penting, yaitu:

 From: Mendapatkan atau menetapkan nilai permulaan dari Animation. Jika


dihilangkan, Animation menggunakan nilai properti saat ini.
 To: Mendapatkan atau menetapkan nilai akhir dari Animation.
160 WPF, Just Code It!

 By: Mendapatkan atau menetapkan jumlah yang digunakan untuk meningkatkan


nilai dari properti target selama berjalannya Animation. Jika properti To maupun
By ditetapkan, nilai properti By dibiarkan saja.

Contoh berikut mendemonstrasikan sebuah animasi yang sangat sederhana. Animasi ini
mengubah nilai dari sebuah properti yang memiliki representasi tipe data Double dari 1
hingga 200 salama berjalan 10 detik:

<DoubleAnimation Duration="0:0:10" From="1" To="200" />

Didalam contoh ini, properti Duration menetapkan durasi 10 detik untuk animasi
tersebut, serta properti From dan To menAndakan nilai awal sebesar 1 dan nilai akhir
sebesar 200.

8.2.2 StoryBoards

StoryBoard adalah elemen inti dari animasi. StoryBoards harus ada didalam sebuah
elemen BeginStoryBoard didalam event triggers. Setiap StoryBoard terdiri dari satu atau
lebih tipe animasi dasar untuk menganimasikan sebuah kontrol. Elemen ini memiliki dua
properti penting: StoryBoard.TargetName dan StoryBoard.TargetProperty. Storyboard
menetapkan nama elemen yang harus dianimasikan dan TargetName menetapkan
properti elemen yang harus dianimasikan oleh StoryBoard. StoryBoard.TargetProperty
harus ditetapkan ke properti yang benar berdasarkan pada hirarki elemen, sub-elemen
dan atribut didalam XAML.

Didalam StoryBoard Anda dapat menaruh satu atau lebih tipe animasi dasar
berdasarkan pada animasi yang ingin Anda bangun. Berikut adalah contoh kode untuk
menggunakan sebuah StoryBoards.

<Window x:Class="UniveRSS.Animations.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
161 WPF, Just Code It!

Title="Animations in WPF" Height="300" Width="300">


<Grid>
<Grid.Triggers>
<EventTriggerRoutedEvent="Rectangle.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard Storyboard.TargetName="myButton"
Storyboard.TargetProperty="(Background).
(SolidColorBrush.Color)">
<ColorAnimation From="Pink"
To="Green"
By="Blue"
Duration="0:0:6" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Grid.Triggers>
<Button Name="myButton" Width="150" Height="35" Background="Pink">
Click Me!
</Button>
</Grid>
</Window>

Didalam kode XAML diatas, warna background dari Button beranimasi dari Pink menjadi
Blue kemudian menjadi Green dalam 6 detik kapanpun pengguna menggerakkan mouse
diatas Button tersebut.
162 WPF, Just Code It!

Gambar 8.1 Animasi warna pada sebuah Button

8.2.3 Repeat Behaviour

Dengan menggunakan dua properti, Anda dapat mengubah perilaku dari animasi Anda
dalam dua cara. Anda dapat membalik animasi dengan menetapkan properti
AutoReverse dari setiap tipe animasi menjadi true. Anda juga dapat menetapkan
RepeatBehavior dari setiap tipe animasi dalam rangka mengatur jumlah iterasi untuk
masing-masing animasi. Anda dapat menetapkan properti ini menjadi Forever agar
animasi Anda berjalan selamanya (sampai Anda menghentikan aplikasi).

Contoh berikut mendemonstrasikan animasi terbalik dari animasi pada contoh


sebelumnya yang berjalan tiga kali.

<Window x:Class="UniveRSS.Animations.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Animations in WPF" Height="300" Width="300">
<Grid>
<Grid.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard Storyboard.TargetName="myButton"
Storyboard.TargetProperty="(Background).
(SolidColorBrush.Color)">
163 WPF, Just Code It!

<ColorAnimation From="Pink"
To="Green"
By="Blue"
Duration="0:0:6"
RepeatBehavior="3x"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Grid.Triggers>
<Button Name="myButton" Width="150" Height="35" Background="Pink">
Click Me!
</Button>
</Grid>
</Window>

Gambar 8.2 Animasi warna AutoReverse dan RepeatBehavior pada sebuah Button

8.2.4 Transformasi

Transformasi adalah cara lain untuk menganimasikan kontrol. Dengan menggunakan


transformasi Anda dapat mengubah sudut dari masing-masing kontrol yang merupakan
cara umum untuk menganimasikan obyek-obyek didalam UI. Untuk melakukan
transformasi, Anda harus menggunakan satu DoubleAnimation untuk mengubah
RenderTransform dari sebuah obyek ketika sebuah event terjadi.
164 WPF, Just Code It!

Contoh berikut menggunakan transformasi untuk mengubah sudut dari


RotateTransform untuk mentransformasi sebuah Button dari 0 menjadi 180 derajat
dalam 6 detik.

<Window x:Class="UniveRSS.Animations.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Animations in WPF" Height="300" Width="300">
<Grid>
<Grid.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard Storyboard.TargetName="myButton"
Storyboard.TargetProperty="(RenderTransform).
(RotateTransform.Angle)">
<DoubleAnimation From="0"
To="180"
By="90"
Duration="0:0:6"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Grid.Triggers>
<Button Name="myButton" Width="150" Height="35" Background="Pink">
Click Me!
</Button>
</Grid>
</Window>
165 WPF, Just Code It!

Gambar 8.3 Transformasi sebuah Button

8.2.5 ParallelTimeLine

Kadangkala Anda perlu menciptakan dua atau lebih animasi yang berjalan secara
paralel. Hal ini sangat mudah diwujudkan didalam WPF. Yang perlu Anda lakukan
hanyalah meletakkan StoryBoards Anda didalam elemen ParallelTimeLine didalam
StoryBoard induk. Dengan cara ini, semua StoryBoards tersebut dan animasi mereka
akan berjalan secara paralel.

Berikut adalah contoh dari ParallelTimeLine dimana sebuah Button dianimasikan untuk
berubah warna backgroundnya sembari sudut RenderTransform nya berubah dari 0 ke
180 derajat. Anda tinggal menggabungkan dua animasi yang telah Anda buat dalam
contoh pertama dan contoh ketiga.

<Window x:Class="UniveRSS.Animations.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Animations in WPF" Height="300" Width="300">
<Grid>
<Grid.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ParallelTimeline>
166 WPF, Just Code It!

<Storyboard Storyboard.TargetName="myButton"
Storyboard.TargetProperty="(Background).
(SolidColorBrush.Color)">
<ColorAnimation From="Pink"
To="Green"
By="Blue"
Duration="0:0:6" />
</Storyboard>
<Storyboard Storyboard.TargetName="myButton"
Storyboard.TargetProperty="(RenderTransform).
(RotateTransform.Angle)">
<DoubleAnimationFrom="0"
To="180"
By="90"
Duration="0:0:6" />
</Storyboard>
</ParallelTimeline>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Grid.Triggers>
<Button Name="myButton" Width="150" Height="35"
Background="Pink">
<Button.RenderTransform>
<RotateTransform Angle="0"CenterX="105"CenterY="30" />
</Button.RenderTransform>
Click Me!
</Button>
</Grid>
</Window>
167 WPF, Just Code It!

Gambar 8.4 Animasi Paralel untuk sebuah Button

8.2.6 KeyFrame

Secara default, semua tipe animasi built-in menggunakan sebuah cara simetris untuk
menganimasikan elemen-elemen dan membagi waktu total menjadi frame-frame yang
sebanding. Namun kadangkala Anda perlu mengatur panjang waktu dimana masing-
masing frame animasi muncul dalam keluaran. Dalam kasus ini, Anda dapat
mendeklarasikan nilai-nilai yang berbeda untuk frame-frame yang berbeda dengan
menggunakan tipe-tipe KeyFrames yang berbeda.

Setiap tipe animasi dasar memiliki sebuah KeyFrame yang bersesuaian agar Anda dapat
mendeklarasikan KeyFrame untuk tipe tersebut. Pada contoh berikut,
LinearDoubleKeyFrames digunakan untuk mengubah Width dari sebuah Button dari 60
menjadi 120 dengan nilai-nilai yang berbeda pada setiap frame waktu.

<Window x:Class="UniveRSS.Animations.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Animations in WPF" Height="300" Width="300">
<Grid>
<Grid.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard Storyboard.TargetName="myButton"
168 WPF, Just Code It!

Storyboard.TargetProperty="Width">
<DoubleAnimationUsingKeyFrames Duration="0:0:8">
<LinearDoubleKeyFrame KeyTime="0:0:2" Value="60"/>
<LinearDoubleKeyFrame KeyTime="0:0:4" Value="80"/>
<LinearDoubleKeyFrame KeyTime="0:0:6" Value="100"/>
<LinearDoubleKeyFrame KeyTime="0:0:8" Value="120"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Grid.Triggers>
<Button Name="myButton" Width="60" Height="35" Background="Pink">
Click Me!
</Button>
</Grid>
</Window>

Gambar 8.5 Animasi LinearDoubleKeyFrames untuk sebuah Button


169 WPF, Just Code It!

8.3 Kesimpulan

Salah satu hal yang menarik dari sebuah aplikasi adalah sisi dinamis dari aplikasi
tersebut. Kedinamisan Aplikasi dapat dicapai melalui teknik animasi dan kekayaan
multimedia aplikasi itu sendiri. WPF menghadirkan secara built-in teknologi multimedia
dan animasi, bayangkan pada masa sebelum era WPF yang masih bergantung pada
active-x animasi dan multimedia pihak ketiga yang harus Anda peroleh di luar sana.
170 WPF, Just Code It!

9 WPF Interoperability

Interoperabilitas adalah kemampuan suatu platform/teknologi untuk dapat


berkomunikasi dengan platform/teknologi lain, baik secara langsung atau melalui suatu
broker yang dikenal dengan middleware.

9.1 Interoperabilitas WPF dan Windows Form

WPF secara langsung mendukung dua teknik yang memungkinkan terjadinya


interoperabilitas dengan teknologi Windows Form, yaitu:

 Host Kontrol WPF didalam Windows Form. Pada bagian ini kunci utamanya
adalah kelas ElementHost yang menangani komunikasi kontrol WPF didalam
Windows Form.

 Host Kontrol Windows Forms didalam WPF. Pada mekanisme ini kunci utamanya
adalah kelas WindowsFormHost yang menjadi kontainer kontrol Windows Form
didalam WPF.

Kedua kemampuan ini menarik sebagai contoh hosting kontrol WPF kedalam Windows
Form yang akan memfasilitasi pihak-pihak yang telah memiliki investasi kode di
Windows Form untuk meningkatkan UX aplikasinya dengan menambahkan WPF
Contents, hal yang sebaliknya juga berlaku pada kondisi-kondisi tertentu.

9.1.1 Investasi didalam Windows Forms ke WPF

Jika Anda ingin mendayagunakan kembali investasi kode Anda didalam aplikasi Windows
Forms dan menikmati fitur-fitur canggih dari WPF, Anda dapat memilih untuk
menyimpan aplikasi Windows Forms Anda tetap utuh dan memigrasi bagian-bagian dari
aplikasi Anda ke WPF. Anda dapat melakukannya dengan mengidentifikasi area-area
171 WPF, Just Code It!

dari aplikasi Anda yang sesuai denan fitur-fitur WPF dan mengkonversi area-area
tersebut ke WPF. Sebagai contoh, Anda mungkin ingin mengkonversi beberapa form
Anda ke WPF. Dengan menggunakan metode ini, Anda hanya akan memunculkan
instan-instan halaman-halaman atau jendela-jendela WPF dari aplikasi Windows Forms
Anda. Apalagi, Anda mungkin ingin benar-benar mengeluarkan kontrol-kontrol Windows
Forms ke kontrol-kontrol WPF pada sebuah form yang menghasilkan form hibrid dan
kontrol-kontrol tersebut bisa berdampingan dengan selaras.

9.1.2 Hosting Kontrol Windows Form didalam Aplikasi WPF

Untuk meletakkan kontrol-kontrol Windows Form didalam Aplikasi WPF, pertama


pastikan untuk menambahkan referensi System.Windows.Forms dan
System.Windows.Forms.Integration. Kemudian Anda perlu memutuskan apakah Anda
akan menggunakan kode, XAML atau kombinasi keduanya untuk bekerja dengan
kontrol-kontrol Windows Forms. Jika Anda menggunakan kode, tuliskan kode seperti
berikut:

//Instantiate the hosting control


WindowsFormsHost host = new WindowsFormsHost();

//Instantiate the Windows Forms control, in this case a button


System.Windows.Forms.Button wfButton = new
System.Windows.Forms.Button();
wfButton.Text = "Windows Forms Button";

// Add the Windows Forms button to the host control


host.Children.Add(wfButton);

// Add the host control to the WPF element that you want to parent the
// control, in this case it's a Grid
this.grid1.Children.Add(host);
172 WPF, Just Code It!

Jika Anda menggunakan XAML, Anda masih harus menambahkan referensi


System.Windows.Forms dan System.Windows.Forms.Integration, namun Anda juga
perlu menambahkan pernyataan mapping (pemetaan) ke XAML Anda yang akan
mengijinkan Anda untuk mengacu obyek-obyek yang hidup didalam namespaces via
XAML:

<?Mapping XmlNamespace="wfi"
ClrNamespace="System.Windows.Forms.Integration"
Assembly="WindowsFormsIntegration"?>
<?Mapping XmlNamespace="wf" ClrNamespace="System.Windows.Forms"
Assembly="System.Windows.Forms"?>

Properti XmlNamespace menyediakan jalan untuk menciptakan sebuah tag yang dapat
Anda gunakan sebagai prefiks namespace didalam XAML untuk mengacu ke kontrol-
kontrol didalam namespace System.Windows.Forms dan
System.Windows.Forms.Integration. Untuk mengaktifkannya, Anda juga harus
menciptakan properti xmlns didalam XAML yang memetakan kembali ke prefiks-prefiks
tersebut:

<Window x:Class="AvalonApplication17.Window1"
xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"
xmlns:wfi="wfi"
xmlns:wf="wf"
Title="AvalonApplication17"
Loaded="WindowLoaded"
>

Kemudian Anda dapat menggunakan XAML untuk menginstansiasi kontrol


WindowsFormsHost dan kontrol-kontrol anaknya:

<Grid x:Name="grid1">
<wfi:WindowsFormsHost>
<wf:Button Text="Windows Forms Button"/>
</wfi:WindowsFormsHost>
</Grid>
173 WPF, Just Code It!

9.1.3 Hosting Kontrol WPF didalam Aplikasi Windows Form

Untuk meletakkan kontrol-kontrol WPF didalam aplikasi Windows Form, pertama


tambahkan referensi ke WPF namespaces (PresentationCore, PresentationFramework,
UIAutomationProvider, UIAutomationTypes, dan WindowsBase). Selanjutnya ciptakan
sebuah instan dari kontrol ElementHost dan kontrol yang ingin Anda tempelkan didalam
aplikasi Windows Forms dan kemudian relai kontrol tersebut ke kontrol ElementHost.
Kemudian tinggal tambahkan kontrol ElementHost ke koleksi kontrol Forms Anda:

ElementHost host = new ElementHost();


System.Windows.Controls.ListBox wpfListBox = new
System.Windows.Controls.ListBox();
for (int i = 0; i < 10; i++)
{
wpfListBox.Items.Add("Item " + i.ToString());
}
host.Dock = DockStyle.Fill;
host.Controls.Add(wpfListBox);
this.panel1.Controls.Add(host);

Meskipun demikian, jika Anda ingin menggunakan XAML untuk mendeskripsikan kontrol
WPF yang ingin Anda gunakan didalam aplikasi Windows Forms, Anda perlu
menambahkan sebuah item UserControl ke proyek Anda. Hal ini akan menciptakan
berkas UserControl1.xaml dan berkas UserControl1.xaml.cs. Kemudian Anda dapat
memodifikasi berkas UserControl1.xaml untuk memuat XAML yang ingin Anda gunakan
untuk mendeskripsikan kontrol Anda. Kemudian Anda tinggal menciptakan sebuah
instan dari kontrol ini dan menambahkannya ke kontrol ElementHost seperti contoh
berikut:

ElementHost host = new ElementHost();


UserControl1 uc1 = new UserControl1();
host.Controls.Add(uc1);
host.Dock = DockStyle.Fill;
this.panel1.Controls.Add(host);
174 WPF, Just Code It!

Sebagai tambahan, Anda perlu memodifikasi berkas proyek tersebut karena Windows
Application tidak mengetahui apa yang harus dilakukan dengan berkas XAML. Anda
harus membuka berkas proyek (.csproj, .vbproj, etc.) didalam sebuah editor seperti
Notepad dan kemudian gulung kebawah. Anda akan melihat baris berikut:

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

Anda harus menyalin baris ini dan menempelkannya dibawah baris tersebut dan
kemudian ubah "CSharp" menjadi "WinFX" sehingga kedua baris tersebut terlihat
seperti:

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />


<Import Project="$(MSBuildBinPath)\Microsoft.WinFx.targets" />

Sekarang simpan berkas ini dan muat kembali proyek tersebut menggunakan Visual
Studio dan jalankan aplikasi tersebut.

9.2 ClickOnce Deployment

ClickOnce menyediakan berbagai kontrol selama instalasi aplikasi Anda. Anda dapat
mengkonfigurasi aplikasi untuk stand-alone deployment atau mengharuskan pengguna
untuk menjalankan aplikasi dari sebuah server. Bagian ini menjelaskan berbagai opsi
yang dihadirkan oleh ClickOnce deployment.

9.2.1 Menyebarkan dengan ClickOnce

ClickOnce adalah sebuah teknologi penyebaran yang mengijinkan Anda untuk


menciptakan self-updating applications yang dapat diinstal dari berbagai media dan
membutuhkan interaksi pengguna yang minimal. Aplikasi WPF apapun dapat dipublikasi
sebagai sebuah aplikasi ClickOnce, yang mencakup Windows applications, Navigation
applications, dan XBAPs. Anda dapat menggunakan ClickOnce untuk menciptakan
175 WPF, Just Code It!

aplikasi-aplikasi yang disebarkan dari sebuah Web site, file share, atau CD-ROM. Anda
dapat mengkonfigurasi aplikasi ClickOnce untuk dijalankan hanya ketika pengguna
online atau ketika off-line.

Aplikasi ClickOnce terisolasi dari sisa sistem. Karena mereka seutuhnya memuat dirinya
sendiri, mereka tidak berbagi komponen dengan aplikasi-aplikasi lain yang terinstal pada
komputer dan tidak beresiko merusak instalasi aplikasi lain.

Windows applications dan Navigation applications membutuhkan kepercayaan penuh


untuk diinstal pada sebuah komputer lokal via ClickOnce, namun XBAPs dan aplikasi-
aplikasi yang berjalan secara online dieksekusi didalam Internet security zone secara
default (atau didalam Internet security zone lokal jika mereka dijalankan dari sebuah file
share pada intranet lokal).

9.2.2 Menyebarkan sebuah Aplikasi Menggunakan ClickOnce

Anda dapat menyebarkan sebuah aplikasi secara langsung didalam Visual Studio dari tab
Publish dari kotak dialog Project properties. Untuk membuka tab Publish, klik kanan
proyek didalam Solution Explorer, pilih Properties, dan kemudian pilih tab Publish.
Terbukalah Publish properties page.
176 WPF, Just Code It!

Gambar 9.1 Publish properties page

Anda dapat mempublikasikan aplikasi Anda menggunakan ClickOnce dengan mengatur


properti Publish didalam halaman ini dan kemudian klik Publish Now.

9.2.3 Mengkonfigurasi ClickOnce Update Options

ClickOnce mengijinkan Anda untuk mengkonfigurasi aplikasi untuk memeriksa update


secara otomatis.

9.2.3.1 Mengkonfigurasi Update Settings dengan Visual Studio

Untuk memungkinkan aplikasi memeriksa update, pilih check box yang berlabel The
Application Should Check For Updates. Hal ini mengaktifkan opsi-opsi lain didalam kotak
dialog.
177 WPF, Just Code It!

Anda dapat menentukan kapan aplikasi memeriksa update dengan memilih salah satu
antara After The Application Starts atau Before The Application Starts. Jika Anda
memilih Before The Application Starts, aplikasi memeriksa update baru setiap kali
aplikasi dijalankan. Hal ini memastikan bahwa pengguna selalu menjalankan aplikasi
versi terbaru, namun hal ini juga memperlambat performa aplikasi pada saat startup.

Jika Anda memilih After The Application Starts, Anda dapat menentukan bahwa aplikasi
memeriksa update setiap kali aplikasi dijalankan, atau pada interval waktu yang
diinginkan dengan memilih opsi yang sesuai dibawah Specify How Frequently The
Application Should Check For Updates. Anda juga dapat menentukan versi minimum
yang dibutuhkan untuk aplikasi, dan Anda dapat menentukan lokasi yang berbeda untuk
update jika update Anda diletakkan didalam sebuah lokasi yang berbeda dari lokasi
instalasi.

9.2.3.2 Memuat Updates Secara Programatik

Anda mungkin ingin memberikan opsi bagi pengguna untuk memeriksa update, selain
menggunakan jadwal. Anda dapat menambahkan fungsionalitas kedalam aplikasi Anda
untuk memeriksa dan menginstal update secara manual. Sebagai contoh, Anda mungkin
menyediakan sebuah opsi menu yang bernama Check For Updates.

Anda dapat memeriksa update didalam kode dengan menggunakan kelas


ApplicationDeployment. Kelas ini merepresentasikan sebuah ClickOnce deployment.
Untuk menggunakan kelas ini didalam kode, pertama Anda harus menambahkan sebuah
referensi ke System.Deployment. Setelah referensi ini ditambahkan, Anda bisa
mendapatkan kembali sebuah instan yang merepresentasikan current deployment dari
properti statsi CurrentDeployment, seperti:

System.Deployment.Application.ApplicationDeployment aDep;
aDep =
System.Deployment.Application.ApplicationDeployment.CurrentDeployment;
178 WPF, Just Code It!

Setelah Anda memperoleh sebuah referensi ke current deployment, Anda dapat


memeriksa update menggunakan metode CheckForUpdate, dan jika update tersedia,
Anda dapat mengupdate aplikasi menggunakan metode Update, seperti:

if (aDep.CheckForUpdate())
{
aDep.Update();
}

Metode CheckForUpdate dan Update juga memiliki rekanan asinkron, yang berturut-
turut disebut CheckForUpdateAsync dan UpdateAsync, yang dapat digunakan untuk
melakukan update secara asinkron. Ketika CheckForUpdateAsync kembali, ia
membangkitkan event CheckForUpdateCompleted. Dengan menangani event ini, Anda
dapat melakukan query terhadap argumen Check-ForUpdateCompletedEventArgs
didalam event handler untuk menentukan apakah sebuah update tersedia. Jika update
tersedia, Anda dapat memanggil UpdateAsync untuk mengunduh dan menginstal
update secara asinkron. Jika aplikasi sedang berjalan, maka update diterapkan setelah
aplikasi berakhir, sehingga update tidak akan terlihat sampai aplikasi di-restart.

Teknik ini didemostrasikan didalam contoh berikut:

System.Deployment.Application.ApplicationDeployment aDep;
public myApplication
{
InitializeComponent();
aDep=System.Deployment.Application.ApplicationDeployment.CurrentDeplo
yment;
aDep.CheckForUpdateCompleted += UpdateCheckCompleted;
}

public void UpdateApp()


{
aDep.CheckForUpdateAsync();
}
179 WPF, Just Code It!

private void UpdateCheckCompleted(object sender,


System.Deployment.Application.CheckForUpdateCompletedEventArgs e)
{
if (e.UpdateAvailable)
{
aDep.UpdateAsync();
}
}

9.2.3.3 Memigrasi Settings dan User Data

Application settings dan default user settings disimpan didalam berkas .config milik
aplikasi. Biasanya pengaturan-pengaturan tersebut diupdate dengan setiap update
aplikasi baru. Meskipun demikian, user settings yang telah dimodifikasi oleh pengguna
disimpan didalam sebuah berkas lokal yang terpisah dari berkas .config. Sehingga tidak
ada usaha tambahan yang dibutuhkan untuk memigrasi user settings ketika sebuah
aplikasi diupdate.

9.2.4 Menyebarkan sebuah XBAP dengan ClickOnce

Dengan ClickOnce, XBAPs dapat disebarkan dalam cara yang sama seperti sebuah
Windows application atau Navigation application. Semua properti publikasi ClickOnce
juga diterapkan ke XBAPs, namun ada sedikit yang khusus untuk XBAP saja.

XBAPs berjalan didalam browser dan biasanya dijalankan dari sebuah Web site.
Sehingga, mereka hampir selalu berjalan dibawah partial trust. Anda harus merancang
aplikasi XBAP Anda untuk eksekusi didalam lingkungan partial-trust dan menguji mereka
didalam lingkungan kepercayaan yang sama dengan lingkungan yang akan digunakan
oleh pengguna.

9.2.4.1 Pertimbangan untuk Menyebarkan didalam Lingkungan Partial-Trust


180 WPF, Just Code It!

Ketika merancang sebuah aplikasi untuk eksekusi didalam sebuah lingkungan partial-
trust, Anda harus menghindari fitur-fitur kode yang membutuhkan akses ke sumber
daya sistem terproteksi. Sebagai contoh, Anda tidak boleh mencoba untuk mengakses
sistem berkas atau registry didalam sebuah XBAP. Anda dapat menggunakan tool-tool
built-in untuk mengindikasi ijin-ijin yang dibutuhkan oleh aplikasi Anda.

9.2.4.1.1 Mengkonfigurasi Kebutuhan Keamanan Akses Kode

Anda dapat mengkonfigurasi kebutuhan keamanan akses kode pada Security properties
page, yang dapat Anda akses dengan klik kanan proyek Anda, pilih Properties, dan
kemudian pilih tab Security.

Anda dapat mengkonfigurasi ijin-ijin yang diminta oleh aplikasi Anda didalam halaman
ini dengan memilih Enable ClickOnce Security Settings check box dan kemudian memilih
radio button yang berlabel This Is A Partial Trust Application. ClickOnce Security
Permissions group dibawah radio button ini digunakan untuk mengkonfigurasi ijin yang
diminta oleh aplikasi Anda.

Anda apat menetapkan ijin-ijin yang diminta menjadi defaults yang diperbolehkan oleh
Internet atau local intranet zones dengan memilih zona didalam drop-down box berlabel
Zone Your Application Will Be Installed From. Anda juga dapat menciptakan permintaan
keamanan khusus dengan memilih (Custom) didalam drop-down box dan kemudian
secara individual mengatur setiap ijin menjadi Include atau Exclude didalam kolom
Setting. Jika ijin-ijin yang diminta melanggar kebijakan keamanan lokal dari komputer
yang mengeksekusi, aplikasi tidak akan dijalankan.

Berikut adalah daftar operasi-operasi umum yang tidak aman didalam lingkungan
partial-trust.
181 WPF, Just Code It!

Tabel 9.1 Fitur-fitur yang tidak aman digunakan dalam lingkungan Partial-Trust
Fitur Fitur-fitur Area
General Window (Application-Defined Windows and Dialog Boxes)
SaveFileDialog
File System
Registry Access
Drag And Drop
XAML Serialization (via XamlWriter.Save)
UIAutomation Clients
Source Window Access (HwndHost)
Full Speech Support
Windows Forms Interoperability
Web Web Services (using Windows Communication Foundation)
Integration Scripting
Document Object Model
Visuals Bitmap Effects
Editing Rich Text Format Clipboard
Full XAML support

Ketika menuliskan aplikasi yang mungkin disebarkan didalam lingkungan partial-trust,


Anda sebisa mungkin menghindari penggunaan fitur-fitur yang terdaftar didalam tabel
9.1. Untuk aplikasi-aplikasi yang mungkin dijalankan dikedua lingkungan, partial trust
dan full trust, Anda dapat menggunakan Code Access Security (CAS) untuk memeriksa
saat run time apakah sebuah operasi khusus diijinkan.

Contoh berikut mendemonstrasikan penciptaan sebuah Demand untuk FileIOPermission


untuk menentukan apakah aman untuk menulis ke sebuah berkas. Jika aplikasi tidak
memiliki ijin untuk menulis ke berkas yang diinginkan, sebuah eksepsi dilemparkan:

try
{
182 WPF, Just Code It!

System.Security.Permissions.FileIOPermission perm =
new System.Security.Permissions.FileIOPermission(
System.Security.Permissions.FileIOPermissionAccess.AllAccess,
"C:\\myFile");
perm.Demand();
// proceed with writing the file
}
catch
{
// recover from being unable to write the file
}

9.3 Kesimpulan

Tidak semuanya dikembangkan mulai dari nol, sekiranya itulah pesan pada bab ini. WPF
memungkinkan kita untuk melakukan mekanisme interoperabilitas ditingkat teknologi.
Walaupun pada bab ini dikemukakan bahwa interoperabilitasnya sebatas teknologi lain
yang berumpun dari .NET , hal ini akan cukup membantu bagi para pengembang yang
telah memiliki cukup investasi pada kode sebelumnya. Sama halnya dengan dukungan
kompatibilitas, aplikasi WPF juga mendukung distribusi ala Smart Client yang telah lama
diusung pada .NET Framework. Pengembang dapat mendeploy aplikasi WPF sebagai
aplikasi standalone atau yang berjalan di atas browser (XBAP) dan kesemuanya
didukung oleh teknologi dengan nama Smart Client.

You might also like