1 2 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 adala...
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 jargonjargon 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
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
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
6.3.1
Mengasosiasikan ValidationRules dengan Binding.........................................134
6.3.2
Menyediakan Umpan Balik Visual ..................................................................136
6.4 7
Validasi Data ...........................................................................................................134
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 9.2.4.1
Menyebarkan sebuah XBAP dengan ClickOnce ..............................................179 Pertimbangan untuk Menyebarkan didalam Lingkungan Partial-Trust ......179
9.2.4.1.1 Mengkonfigurasi Kebutuhan Keamanan Akses Kode ...........................180 9.3
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 dihost 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 diskrol 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 fiturfitur 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 instruksiinstruksi render, seperti instruksi kliping dan transformasi, bersama dengan atributatribut 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 perubahanperubahan 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 perubahanperubahan 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 komponenkomponen 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 dimarkup 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 batasanbatasan 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 kelaskelas 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
PageFunction.Returned ke event handler yang baru, seperti:
merelai
event
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, Panelpanel 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>
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.
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" />
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 perubahanperubahan 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" />
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" />
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
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:
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" />
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
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 obyekobyek 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
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 bentukbentuk 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 deviceindependent.
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: <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:
Contoh berikut memperlihatkan beberapa cara untuk menggambarkan koordinatkoordinat garis dan properti stroke:
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 titiktitik berikutnya didalam koleksi, dan selesai pada titik terakhir didalam koleksi. Contoh berikut menggambarkan sebuah Polyline dengan shape gigi gergaji:
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!
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
Default: 1.0
Default: 0.0
M21
M22
Default: 0.0
Default: 1.0
OffsetX
OffsetY
Default: 0.0
Default: 0.0
0.0
0.0
1.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 RotateTransform
Deskripsi
Ilustrasi
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
76
WPF, Just Code It!
Didalam contoh berikut, shape lain dirotasi 45 derajat, namun kali ini ia dirotasi pada titik (25,50). XAML
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">
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"> Flipped 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"> Flipped 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">
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">
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>
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 <SolidColorBrush Color="Red" />
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));
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 masingmasing 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
LinearGradientBrush.StartPoint
dan
dengan
menggunakan
LinearGradientBrush.EndPoint.
properti 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 lingkaranlingkaran 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
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
/>
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));
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 <StackPanel> <StackPanel.Background>
89
WPF, Just Code It!
Hello, World!
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);
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
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
94
WPF, Just Code It!
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 <EllipseGeometry Center="50,50" RadiusX="50"
RadiusY="50"/>
<EllipseGeometry Center="150,150" RadiusX="50"
RadiusY="50"/>
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; } } }
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 shapeshape 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"/>
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> <EllipseGeometry RadiusX="40" RadiusY="50"/>
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> <EllipseGeometry RadiusX="40" RadiusY="50"/>
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:
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:
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:
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 kontrolkontrol 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: Button 1 Button 2 Button 3 Button 4
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"> Button 1Button 2 <StackPanel Height="34" Margin="0,34,0,0" VerticalAlignment="Top"> Button 3Button 4
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: Here is some text
Jika Anda ingin mengubah teks didalam TextBlock didalam kode, Anda harus menetapkan properti Name dari TextBlock sehingga Anda dapat mengacunya didalam kode, seperti: Here is some text
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 Hello, world!
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 is designed to be lightweight, and is geared specifically at integrating small portions of flow content into a UI. <Button Width="100" Margin="10">Click Me
Name="textBlock2"
> By default, a TextBlock provides no UI beyond simply displaying its contents. <Button Width="100" Margin="10">Click Me
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
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:
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:
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:
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:
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: ThisIsAList
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 itemitem yang diinginkan.
Anda dapat menetapkan properti SelectionMode didalam XAML seperti:
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: Option 1Option 2Option 3Option 4
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 itemitem yang menyusun koleksinya. Berikut adalah contoh untuk menciptakan sebuah 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 itemitem 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"/>
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"/>
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: <MenuItem Header="Cut" Command="ApplicationCommands.Cut"/> <MenuItem Header="Copy" Command="ApplicationCommands.Copy"/> <MenuItem Header="Paste" Command="ApplicationCommands.Paste"/>
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: <Button>Back <Button>Forward
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 kontrolkontrol 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.
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, elemenelemen yang diikatkan ke data tersebut secara otomatis merefleksikan perubahanperubahan 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# <Button Background="{Binding Path=ColorName}" Width="150" Height="30">Saya di ikat berwarna merah!
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# <Button Width="150" Height="30" Background="{Binding Source={StaticResource myDataSource}, Path=ColorName}">Saya diikat berwarna merah!
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#
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 bindingbinding 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:
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:
Untuk kontrol item, Anda menetapkan properti ItemsTemplate, seperti yang bercetak tebal berikut:
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>
Kemudian Anda dapat menetapkan template dengan mengacunya ke sumber daya, seperti yang bercetak tebal berikut:
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!
<ExceptionValidationRule />
Properti ValidationRules
mengambil
koleksi
dari
obyek-obyek ValidationRule.
ExceptionValidationRule adalah sebuah ValidationRule built-in yang memeriksa eksepsieksepsi 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# <src:FutureDateRule />
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# !
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> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
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-atime, 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.
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 . 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
FlowDocumentPageViewer,
views dan
(DocumentViewer, FlowDocumentReader)
FlowDocumentScrollViewer, 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 elemenelemen 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
CopyToOutputDirectory menjadi PreserveNewest atau Always.
8.1.2 Mode Playback Media
dan
menetapkan
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 metodemetode ini hanya tersedia ketika LoadedBehavior ditetapkan menjadi Manual. Metodemetode 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# <Page x:Class="MediaElementExample.SimpleUsage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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. Obyekobyek 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 perubahanperubahan 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 Animation, dimana 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 keyframe diberi nama dalam format AnimationUsingKeyFrames, dimana 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
Animation-UsingPath, dimana 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:
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"
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"> <EventTrigger RoutedEvent="Rectangle.MouseEnter"> <EventTrigger.Actions> <Storyboard Storyboard.TargetName="myButton" Storyboard.TargetProperty="(Background). (SolidColorBrush.Color)">
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"> <EventTrigger RoutedEvent="Rectangle.MouseEnter"> <EventTrigger.Actions> <Storyboard Storyboard.TargetName="myButton" Storyboard.TargetProperty="(RenderTransform). (RotateTransform.Angle)"> <Button Name="myButton" Width="150" Height="35" Background="Pink"> Click Me!
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"> <EventTrigger RoutedEvent="Rectangle.MouseEnter"> <EventTrigger.Actions> <Storyboard> <ParallelTimeline>
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 masingmasing 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"> <EventTrigger RoutedEvent="Rectangle.MouseEnter"> <EventTrigger.Actions> <Storyboard Storyboard.TargetName="myButton"
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:
Properti XmlNamespace menyediakan jalan untuk menciptakan sebuah tag yang dapat Anda gunakan sebagai prefiks namespace didalam XAML untuk mengacu ke kontrolkontrol
didalam
namespace
System.Windows.Forms.Integration.
Untuk
System.Windows.Forms mengaktifkannya,
Anda
juga
dan 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
WindowsFormsHost dan kontrol-kontrol anaknya: <wfi:WindowsFormsHost> <wf:Button Text="Windows Forms Button"/>
menginstansiasi
kontrol
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:
Anda harus menyalin baris ini dan menempelkannya dibawah baris tersebut dan kemudian ubah "CSharp" menjadi "WinFX" sehingga kedua baris tersebut terlihat seperti:
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 aplikasiaplikasi 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 berturutturut 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(); }
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 partialtrust, 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 General
Fitur-fitur Area 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.