Pembuatan User Control, dan Custom Control ditujukan salah satunya untuk
membuat efisiensi waktu dalam penggunaan kontrol yang sama di beberapa form.
Terdapat perbedaan yang cukup signifikan didalam desktop application yang
berbasiskan windows forms dengan yang dapat dilakukan di WPF untuk pembuatan
control tersebut.
Didalam windows forms kita kenal dengan adanya fitur Visual Inheritance yang
digunakan untuk membuat template sebuah kontrol atau form yang dapat di extend
behaviournya di dalam container host yang digunakan. Caranya relatif simple
menurut saya. Anda cukup buat sebuah Windows Forms Application yang dirubah
Output Type nya menjadi Class Library (.dll). Didalam project tersebut anda
tinggal tambahkan Form dengan design yang kita anggap nantinya sebagai master
form. Output project tersebut dapat di reference / ditambahkan sebagai Inherited
Form dari project lainnya. Setelah itu anda dapat dengan bebas merubah template
yang sudah ada.
Untuk pembuatan custom control yang extend dari sebuah base class, katakanlah
combobox, cukup dengan menambahkan sebuah class yang diturunkan dari class
control yang ingin anda extend dari sebuah Windows Control Library project.
Cara yang ditempuh di WPF agak sedikit berbeda. Perbedaan terutama dalam hal
data binding dan templating control. Dengan fitur Style kita dapat merubah
template sebuah control. Di dalam style disimpan setting-setting property
kontrol yang bersangkutan dan juga data template yang digunakan untuk templating
control sebagai visualisasi data yang ingin ditampilkan.
Style yang dibuat dapat disimpan didalam sebuah Application-Wide Resource
yang berupa Resource Dictionary atau Application Resources. Sehingga semua
window atau page class dapat menggunakan template style tersebut.
Di asp.net 2.0 ke atas kita sudah mengenal dengan adanya komponen
ObjectDataSourceControl yang digunakan sebagai data source yang meng-consume
object dari sebuah class. WPF juga menyediakan komponen tersebut yang memiliki
fungsionalitas serupa dengan object data source control yang terdapat didalam
asp.net 2.0 keatas.
So, how can we create windows forms-like custom control using declarative way
in WPF?
Ya, dalam artikel ini saya akan buat contoh sederhana untuk membuat "windows
forms-like custom control " dengan declarative code di WPF. Sebelumnya saya
lakukan hal ini didalam windows forms dengan membuat sebuah Windows Control
Library Project, kemudian dibuatkan sebuah class yang diturunkan dari sebuah
control class, misalnya TextBox atau ComboBox. Bindingnya pun dilakukan secara
imperative code.
Ok, saya akan buat sebuah combobox, dimana combobox tersebut itemnya di bind
terhadap sebuah LinqToSql class yang disimpan didalam sebuah library project.
Library tersebut nantinya akan di consume oleh ObjectDataProvider komponen.
ObjectDataProvider inilah nantinya digunakan sebagai data source combobox
tersebut. Style dan DataTemplate akan disimpan didalam sebuah ResourceDictionary
atau Application Resources agar bisa digunakan dari window atau page class
manapun.
Mari kita ikuti langkah-langkahnya :
1. Buat sebuah ClassLibrary project. Tambahkan Linq To Sql Classes item.
Asumsikan nama projectnya MyLib dan nama .dbml file nya MyNorthwind.
2. Drag and Drop Customer table dari database Northwind kedalam OR
designer.
3. Tambahkan sebuah class, beri nama MyNorthwind.Extended.vb. Class ini akan
kita gunakan sebagai partial class yang akan menyimpan sebuah shared method
berupa shared function yang mengembalikan nilai berupa IQueryable(Of Customer).
Berikut kode nya :
Partial Public Class Customer
Public Shared Function GetAllCustomers() As IQueryable(Of Customer)
Dim db As New MyNorthwindDataContext
Return From c In db.Customers
End Function
End Class
4. Build Project.
5. Tambahkan WPF Application project baru kedalam solution yang sama.
6. Buka file Application.xaml, ketikkan kode berikut ini :
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:theLib="clr-namespace:MyLib;assembly=MyLib"
StartupUri="ComboTemplate.xaml">
<Application.Resources>
<ObjectDataProvider x:Key="objCust"
ObjectType="{x:Type theLib:Customer}"
MethodName="GetAllCustomers" />
<Style x:Key="ComboCustomerStyle"
TargetType="{x:Type ComboBox}">
<Setter Property="Width" Value="250" />
<Setter Property="Height" Value="25" />
<Setter Property="ItemsSource"
Value="{Binding Source={StaticResource objCust}}" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=CustomerID}"
Width="50"
VerticalAlignment="Center" />
<TextBlock Text=" | " Margin="0,0,5,0"
VerticalAlignment="Center" />
<TextBlock Text="{Binding Path=CompanyName}"
VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
7. Untuk menggunakan library yang terdapat didalam project yang berbeda kita
harus melakukan referensi terhadap dll yang akan digunakan. Setelah itu anda
tambahkan shortcut xmlns, pada kasus ini anda dapat lihat xml namespace berikut
diatas : xmlns:theLib="clr-namespace:MyLib;assembly=MyLib" .
8. ObjectDataProvider digunakan untuk membaca sebuah method yang terdapat
didalam library. Class yang digunakan yaitu Customer, dan method yang digunakan
yaitu GetAllCustomers.
9. Setelah itu kita tambahkan Style elemen yang digunakan untuk setting
property control, dalam hal ini combobox. Style diatas juga diisi dengan data
template yang bertugas untuk memvisualisasikan data. Saya tidak akan menjelaskan
penggunaan style secara detail disini, mungkin bila ada kesempatan saya akan
bahas di artikel yang lainnya.
10. Buka sebuah window xaml yang terdapat didalam WPF Application yang sama.
Asumsikan saya memiliki sebuah window dengan nama ComboTemplate.xaml yang berisi
kode seperti dibawah ini :
<Window x:Class="ComboTemplate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ComboTemplate" Height="300" Width="400"
WindowStartupLocation="CenterScreen">
<Grid>
<ComboBox Style="{StaticResource ComboCustomerStyle}" />
</Grid>
</Window>
11. Untuk menggunakan data template yang telah dibuat didalam style anda
cukup merubah Style atribut dari combobox control nya. Sebagai info, dari sisi
naming convention apabila kita membuat sebuah Style, diusahakan untuk memberi
nama Style diakhir.
12. Berikut hasilnya :
Dengan kemudahan secara declarative anda cukup merubah style combobox di
window atau page class manapun. Tentunya juga kita dapat melakukan hal yang sama
untuk kontrol lainnya.