Data Binding in Windows 8

Windows RT menyediakan suatu cara yang sederhana dan konsisten untuk menampilkan dan berinteraksi dengan data. Setiap kontrol yang memiliki properti dapat diasosiasikan dengan sumber data. Fitur ini disebut Data Binding, yaitu sebuah proses memberikan asosiasi antara antarmuka dengan lojik aplikasi. Jika data yang di-binding berubah maka tampilan antarmuka juga secara otomatis berubah dan juga sebaliknya jika suatu properti yang ditampilkan di antarmuka berubah, perubahan tersebut dapat kita propagasi kan ke data yang sudah terasosiasi.

image

Data binding dapat kita pandang sebagai jembatan yang menghubungkan sebuah binding target dengan binding source. Sebuah binding memiliki empat komponen, sebuah target binding ,properti target, sumber data dan path dari data yang ingin ditampilkan. Sebagai contoh, kita ingin melakukan binding terhadap TextBox terhadap properti Name dari suatu kelas model Employee. Pada contoh ini target obyek adalah TextBox, target properti adalah properti Text dari TextBox, nilai yang di binding adalah Name dan sumber datanya adalah obyek Employee.

Properti target haruslah sebuah dependency property. Hampir properti UIElement dari kontrol Windows RT merupakan dependency property dan setiap properti ini, kecuali yang sifatnya hanya ­read-only mendukung data binding. Untuk sumber data yang memiliki koleksi benda maka biasanya kontrol antarmuka yang digunakan untuk obyek data binding juga merupakan kontrol yang tipe nya koleksi, seperti ListView,GridView dan FlipView.

Untuk melihat bagaimana tampilan implementasi data binding dalam aplikasi, buatlah sebuah proyek baru, aplikasi Windows Store dengan template Grid App.

image

Pada jendela Solution Explorer buka berkas BindableBase.cs di dalam direktori Common. Kelas ini memiliki satu event yaitu PropertyChanged.

[Windows.Foundation.Metadata.WebHostHidden]

public abstract class BindableBase : INotifyPropertyChanged

{

/// <summary>

/// Multicast event for property change notifications.

/// </summary>

public event PropertyChangedEventHandler PropertyChanged;

protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)

{

if (object.Equals(storage, value)) return false;

storage = value;

this.OnPropertyChanged(propertyName);

return true;

}

protected void OnPropertyChanged([CallerMemberName] string propertyName = null)

{

var eventHandler = this.PropertyChanged;

if (eventHandler != null)

{

eventHandler(this, new PropertyChangedEventArgs(propertyName));

}

}

}

Kelas ini merupakan kelas helper yang dihasilkan oleh template dan sangat berguna untuk membangun aplikasi yang menggunakan fitur data binding. Untuk membuat obyek-obyek model yang dijadikan sumber data, kita dapat membuat kelas turunan dari BindableBase sehingga mewarisi fitur PropertyChanged. Dengan adanya fitur ini maka setiap ada perubahan nilai dari properti tersebut, akan dipropagasikan kepada kontrol yang direkatkan ke data tersebut. Dengan demikian mekanisme perubahan data antara model dan antarmuka dapat dilakukan dengan mudah.

Selanjutnya, bukalah berkas SampleDataSource.cs di dalam direktori DataModel. Di dalam kelas ini terdapat berbagai deklarasi kelas SampleDataCommon dan SampleDataItem. Kelas SampleDataCommon merupakan kelas abstrak yang diturunkan dari kelas BindableBase. Kelas ini berfungsi menjadi kelas bapak SampleDataItem. SampleDataItem merupakan kelas model yang digunakan template Grid App untuk menampilkan data di dalam aplikasi tersebut.

Contoh implementasi kelas model tersebut adalah seperti dibawah ini. Setiap fungsi setter dilakukan pemanggilan fungsi SetProperty yang merupakan fungsi yang didapatkan dari kelas BindableBase. Fungsi ini berguna untuk mempropagasikan perubahan nilai ke kontrol yang mengikat nilai dari model ini.

/// <summary>

/// Generic item data model.

/// </summary>

public class SampleDataItem : SampleDataCommon

{

public SampleDataItem(String uniqueId, String title, String subtitle, String imagePath, String description, String content, SampleDataGroup group)

: base(uniqueId, title, subtitle, imagePath, description)

{

this._content = content;

this._group = group;

}

private string _content = string.Empty;

public string Content

{

get { return this._content; }

set { this.SetProperty(ref this._content, value); }

}

….

Untuk implementasi binding target secara sederhana kita bisa memanfaatkan properti DataContext yang dimiliki kontrol bertipe Page. Setiap obyek yang kita berikan ke dalam DataContext maka setiap elemen yang terdapat pada pohon antarmuka XAML dapat mengakses nilai tersebut. Sebagai contoh, jika kita menginstansiasi kelas SampeDataItem dan kita berikan nilai tersebut ke DataContext, setiap kontrol pada pohon XAML, misalnya TextBlock, akan dapat menampilkan nilai dari anggota kelas tersebut dengan deklarasi binding yang sesuai.

Bukalah berkas GroupedItemsPage.xaml.cs dan tambahkan kode berikut ini di dalam fungsi LoadState. Kita akan membuat instans dari kelas SampleDataItem, memberikan nilai tertentu dan menjadikan nilai tersebut menjadi nilai DataContext. Pada saat ini, suatu kelas bernama data bertipe SampleDataItem telah menjadi sumber data bagi halaman tersebut. Selanjutnya pada antarmuka, kita dapat membuat sebuah kontrol dan menampilkan data dari anggota-anggota kelas SampleDataItem.

protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)

{

// TODO: Create an appropriate data model for your problem domain to replace the sample data

//var sampleDataGroups = SampleDataSource.GetGroups((String)navigationParameter);

//this.DefaultViewModel[“Groups”] = sampleDataGroups;

SampleDataItem data = new SampleDataItem(“1”, “title test”, “subtitle”, null, null, null, null);

this.DataContext = data;

}

Buka GroupedItemsPage.xaml , tepat diatas kontrol GridView tampatkan sebuah TextBlock. Perhatikan untuk sementara GridView diatur agar tidak tampil terlebih dahulu (Visibility=Collapsed) . Atribut Text dari TextBlock kita berikan nilai Title melalui deklarasi binding. Dengan demikian, pada saat runtime, TextBlock akan mencari nilai Title dari apapun obyek yang direkatkan ke dalam DataContext. Karena DataContext kita rekatkan ke kelas SampleDataItem, maka TextBlock akan menampilkan nilai “title test” , nilai dari anggota kelas yang namanya bersesuaian dengan deklarasi binding.

<TextBlock Grid.Row=”2″ Text=”{Binding Title}” Style=”{StaticResource HeaderTextStyle}”/>

<!– Horizontal scrolling grid used in most view states –>

<GridView Visibility=”Collapsed”

Tekanlah F5 untuk melihat hasilnya.

image

Untuk melihat bagaimana implementasi binding target pada template Grid App ini, bukalah berkas GroupedItemsPage.xaml . Perhatikan kontrol GridView pada XAML editor dan Anda seharusnya akan dapat melihat blok kode berikut ini :

<GridView

x:Name=”itemGridView”

AutomationProperties.AutomationId=”ItemGridView”

AutomationProperties.Name=”Grouped Items”

Grid.RowSpan=”2″

Padding=”116,137,40,46″

ItemsSource=”{Binding Source={StaticResource groupedItemsViewSource}}”

ItemTemplate=”{StaticResource Standard250x250ItemTemplate}”

SelectionMode=”None”

IsSwipeEnabled=”false”

IsItemClickEnabled=”True”

ItemClick=”ItemView_ItemClick”>

Untuk kontrol yang bertipe koleksi seperti GridView maka untuk menghasilkan antarmuka berdasarkan jumlah dari koleksi yang di-binding dilakukan dengan memberikan nilai pada atribut ItemsSource. Pada contoh diatas, ItemsSource diberikan nilai {Binding Source = {Static Resource groupedItemsViewsSource}} . Dengan demikian GridView akan berusaha memperoleh nilai dari sebuah resource bernama groupedItemsViewSource.

<CollectionViewSource

x:Name=”groupedItemsViewSource”

Source=”{Binding Groups}”

IsSourceGrouped=”true”

ItemsPath=”TopItems”

d:Source=”{Binding AllGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}”/>

Perhatikan pada bagian atas berkas, setelah <Page.Resources> , terdapat deklarasi CollectionViewSource yang diberi nama groupedItemsViewsSource. CollectionViewSource mengambil nilainya dari variabel. Groups dan mengakses anggota variabel tersebut, yaitu TopItems. Untuk mengetahui nilai Groups mengacu ke variabel yang mana, cobalah scroll ke paling atas hingga tampak deklarasi DataContext seperti dibawah ini :

<common:LayoutAwarePage

x:Name=”pageRoot”

x:Class=”DataBinding.GroupedItemsPage”

DataContext=”{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}”

Dari sini kita sudah mengetahui bahwa Groups mengacu pada suatu nilai dari sebuah variabel DefaultViewModel, yang merupakan nilai dari DataContext pada halaman tersebut. Untuk mengetahui variabel apa yang terdapat pada kata kunci Groups, bukalah berkas GroupedItemsPage.xaml.cs dan perhatikan fungsi LoadState.

protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)

{

// TODO: Create an appropriate data model for your problem domain to replace the sample data

var sampleDataGroups = SampleDataSource.GetGroups((String)navigationParameter);

this.DefaultViewModel[“Groups”] = sampleDataGroups;

}

Ternyata Groups adalah sebuah nilai yang bertipe IEnumerable<SampleDataGroup> sehingga dapat kita simpulkan bahwa sumber data GridView adalah sebuah IEnumerable<SampleDataGroup> , dimana untuk masing-masing SampleDataGroup, memiliki variabel lagi, yaitu sebuah koleksi yang berisi SampleDataItem. Koleksi SampleDataItem ini akan menjadi sumber data masing-masing grup dari GridView tersebut.

Bagian akhir dari proses data binding ini adalah tampilan antarmuka yang menampilkan koleksi dari SampleDataItem. Untuk mengetahui struktur tampilan bagaimana GridView akan menampilkan masing-masing SampleDataItem tersebut, perhatikan blok kode GridView,dimana nilai atribut ItemsTemplate adalah ItemTemplate=”{StaticResource Standard250x250ItemTemplate}”. Dengan demikian kita mengetahui bahwa masing-masing SampleDataItem tersebut ditampilkan dengan menggunakan suatu template bernama Standard250x250ItemTemplate. Bukalah berkas StandardStyles.xaml di dalam direktori Common dan temukan blok kode yang diberi kata kunci Standar250x250ItemTemplate.

<DataTemplate x:Key=”Standard250x250ItemTemplate”>

<Grid HorizontalAlignment=”Left” Width=”250″ Height=”250″>

<Border Background=”{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}”>

<Image Source=”{Binding Image}” Stretch=”UniformToFill” AutomationProperties.Name=”{Binding Title}”/>

</Border>

<StackPanel VerticalAlignment=”Bottom” Background=”{StaticResource ListViewItemOverlayBackgroundThemeBrush}”>

<TextBlock Text=”{Binding Title}” Foreground=”{StaticResource ListViewItemOverlayForegroundThemeBrush}” Style=”{StaticResource TitleTextStyle}” Height=”60″ Margin=”15,0,15,0″/>

<TextBlock Text=”{Binding Subtitle}” Foreground=”{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}” Style=”{StaticResource CaptionTextStyle}” TextWrapping=”NoWrap” Margin=”15,0,15,10″/>

</StackPanel>

</Grid>

</DataTemplate>

Dari deklarasi DataTemplate sekarang kita mengetahui bahwa untuk masing-masing SampleDataItem ditampilkan menggunakan suatu kontrol yang terdiri dari beberapa Text dengan layout StackPanel. Dan anggota dari SampleDataItem yang diakses adalah Title,Subtitle dan Image.

Tekanlah F5 untuk melihat bagaimana hasil data binding tersebut.

image

Memahami dengan baik bagaimana proses data binding bekerja dapat menghemat dan mempermudah kita dalam pengembangan aplikas di Windows 8-style UI. Dengan data binding pemisahan antarmuka dan lojik dapat dilakukan dengan lebih intuitif dan mudah.

Operator Async dan Await

Aplikasi Windows 8-style UI adalah aplikasi dengan antarmuka yang full screen, modern dan responsif. Nilai responsif dicapai dengan memindahkan eksekusi kode sebanyak mungkin diluar UIThread, sehingga setiap waktu UIThread dapat fokus untuk menerima masukan dari pengguna. Windows Runtime mempermudah pemrogram untuk melakukan ini dengan menyediakan banyak API yang asinkronus dan juga memperkenalkan dua operator baru yaitu await dan async yang dapat kita gunakan untuk membuat fungsi-fungsi menjadi asinkronus.

Sebagai pemrogram, kita pun wajib untuk cermat melihat di bagian mana saja kode bisa dibangun dengan gaya asinkronus ini. Dengan pemrograman asinkronus maka aplikasi tidak perlu selalu menunggu operasi yang mungkin memakan waktu lama dan tetap membiarkan antarmuka responsif dan dapat menerima masukan dari pengguna. Untuk fungsi yang asinkronus, secara konvensi dinamakan dengan kata kerja dan diakhiri dengan kata “Async”. Hal ini berlaku untuk berbagai fungsi di dalam API WinRT dan kepada pemrogram juga disarankan untuk mengikuti konvensi ini jika membangun fungsi asinkronus di dalam aplikasi. Setiap fungsi yang hendak dipanggil secara asinkronus , ditandai dengan operator async dan ketika fungsi tersebut dipanggil diberikan operator await.

Untuk memahami penggunaan kedua operator baru tersebut mari kita membuat sebuah program sederhana yang mengimplementasikan mekanisme asinkronus. Silahkan ikuti langkah-langkah dibawah ini :

1. Buatlah sebuah proyek Windows Store dengan template Split App baru dan beri nama Program_Async.

2. Klik OK untuk membuat project.

3. Tambahkan sebuah halaman baru bertipe Basic Page,dan beri nama FeedPage.xaml


4. Pada halaman XAML, tambahkan kode berikut sebelum tag <VisualStateManager.VisualStateGroups>

<StackPanel Grid.Row=”1″ Margin=”120,30,0,0″>

<TextBlock Style=”{StaticResource HeaderTextStyle}”

Text=”Feed Result”/>

<TextBlock Style=”{StaticResource SubheaderTextStyle}” x:Name=”feedOutput”/>

</StackPanel>

5. Buka berkas FeedPage.xaml.cs dan buatlah sebuah fungsi bernama GetTitleFeedAsync. Potongan kode ini akan mengambil sejumlah judul feed dari sebuah website. Karena kembalian dari fungsi ini adalah string dan kita mengingikan fungsi ini dieksekusi secara asinkronus maka kita tambahkan operator Async.

private async Task<String> GetTitleFeedAsync()

{

Windows.Web.Syndication.SyndicationClient client = new SyndicationClient();

// Force the SyndicationClient to download the information.

client.BypassCacheOnRetrieve = true;

Uri feedUri

= new Uri(“http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx&#8221;);

String result = String.Empty;

try

{

// Call SyndicationClient RetrieveFeedAsync to download the list of blog posts.

SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);

// The rest of this method executes after await RetrieveFeedAsync completes.

result = feed.Title.Text + Environment.NewLine;

foreach (SyndicationItem item in feed.Items.Take(10))

{

result += item.Title.Text + “, ” +

item.PublishedDate.ToString() + Environment.NewLine;

}

}

catch (Exception ex)

{

// Log Error.

result =

“I’m sorry, but I couldn’t load the page,” +

” possibly due to network problems.” +

“Here’s the error message I received: ”

+ ex.ToString();

}

return result;

}

Operator await

Perhatikan baris SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri) menggunakan operator await untuk memanggil fungsi asinkronus RetrieveFeedAsync. Bandingkan jika menggunakan blok kode sinkronus misalnya RetrieveFeed ,sehingga kode kita menjadi SyndicationFeed feed = client.RetrieveFeed(feedUri) dibandingkan blok kode yang ditulis sebelumnya. Eksekusi aplikasi akan berhenti hingga RetrieveFeed selesai dieksekusi dan selama aplikasi berhenti maka aplikasi tidak dapat memberikan respon terhadap event yang lain. Penggunaan operator await membuat blok kode tidak terlihat begitu berbeda dengan eksekusi kode sinkronus namun compiler secara otomatis mengeksekusi kode tersebut secara asinkronus.

6. Buat sebuah fungsi baru, kita beri nama InitializeAsync, yang berguna untuk memanggil fungsi GetTitleFeedAsync dan menuliskan hasilnya ke layar. Jangan lupa gunakan operator await karena kita memanggil fungsi asinkronus.

private async Task InitializeAsync()

{

feedOutput.Text = await GetTitleFeedAsync();

}

7. Fungsi InitializeAsync kita panggil di dalam fungsi LoadState. LoadState merupakan fungsi standar bawaan dari template. Fungsi ini akan dipanggil setiap kali halaman FeedPage.xaml dituju.

protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)

{

InitializeAsync();

}

8. Tekan F5 untuk melihat hasilnya.

Hello World Windows 8

Sejak publikasi buku The C Programming Language pada tahun 1978, sudah menjadi tradisi untuk memulai suatu buku pemrograman dengan sebuah program yang menampilkan “hello, world”. Untuk itu demi tidak melanggar tradisi , perjalanan kita pun akan kita mulai dengan membuat aplikasi Windows 8-style UI dan menampilkan “hello world”.

Jalankan Visual Studio dari Windows 8 start screen dan mari mulai belajar.

1. Jalankan Visual Studio 2012 Anda (selanjutnya disebut Visual Studio)

2. Pilih File > New Project

Kotak New Project akan muncul. Panel disebelah kiri akan menyediakan pilihan template yang dapat digunakan

3. Pada panel kiri, klik Installed sehingga akan menampilkan Visual Basic atau Visual C# dan pilih Windows Store.

4. Pilih template Blank App

5. Pada kotak Nama masukkan “HelloWorld”

6. Klik OK untuk membuat project.

Meskipun template Blank App merupakan template yang paling minimum, namun pembuatan proyek aplikasi dengan tipe ini akan menyediakan beberapa file standar yaitu :

· Berkas manifest , yang berisikan deskripsi aplikasi

· Berkas gambar untuk logo pada start screen

· Sebuah gambar (storelogo.png) yang akan menjadi logo aplikasi di Windows Store

· Sebuah gambar yang akan menjadi splash screen ketika aplikasi dijalankan

· File XAML dan berkas kode (App.xaml dan App.xaml.cs)

· Sebuah berkas MainPage.xaml dan berkas kode untuk yang akan dieksekusi ketika aplikasi dijalankan

Berkas MainPage pada template Blank App didasarkan pada template Blank Page yang hanya terdiri dari sedikit kode untuk instansiasi sebuah halaman. Template proyek lainnya yang tersedia pada Visual Studio menyediakan sejumlah kode tambahan dan beberapa berkas pembantu untuk membuat aplikasi berbasis Windows 8-style UI. Pada contoh kali ini kita akan mengganti halaman Main Page menggunakan template lain yang tersedia sehingga kita dapat memanfaatkan sejumlah kode tambahan dan berkas bantuan untuk memulai aplikasi kita.

Untuk mengganti MainPage berikut adalah langkah-langkah yang dilakukan :

1. Pada Solution Explorer , klik kanan MainPage.xaml dan pilih Delete . Klik OK untuk konfirmasi

2. Pilih Project > Add New Item lalu pilih Visual C# dan Windows Store.

3. Pada panel ditengah pilih Basic Page dan berikan nama,misalnya “MainPage”

4. Pilih Add. Jika kita pertama kali menambahkan sebuah halaman pada proyek dengan template Blank App maka Visual Studio akan menambahkan dialog untuk menambahkan secara otomatis berkas-berkas terkait yang diperlukan ke dalam proyek tersebut. Pilih Yes untuk menambahkan berkas tersebut. Berkas akan berada pada direktori Common di dalam proyek.

Kita akan lihat beberapa berkas yang otomatis ditambahkan ketika membuat proyek menggunakan template. App.xaml adalah tempat dimana kita mendefinisikan berbagai hal yang akan digunakan oleh aplikasi. Berkas ini mengandung sebuah Resource Dictionary yang didalamnya mengandung referensi ke berkas StandardStyles.xaml. Berkas ini mengandung berbagai properti standar untuk membuat tampilan ala Windows 8-style UI. Bagi yang akrab dengan pemrograman web, dapat kita anggal berkas ini sebagai berkas CSS untuk mengatur tampilan dari aplikasi. Seperti berkas kode lainnya, disini terdapat fungsi InitializeComponen, yang dihasilkan otomatis oleh Visual Studio.

MainPage.xaml adalah tempat kita mendefinisikan antarmuka dari aplikasi. Kita dapat menambahkan secara langsung melalui XAML atau secara drag and drop melalui antarmuka Visual Studio. Template Basic Page menggunakan LayoutAwarePage. Kelas ini merupakan kelas turuan dari kelas Page yang sudah menyediakan fungsi navigasi,manajemen state dan manajemen tampilan (view management). Basic Page juga menyediakan beberapa konten seperti tombol Back dan teks Title.

Sekarang kita tambahkan konten MainPage.xaml.

1. Pada Solution Explorer , klik dua kali berkas MainPage.xaml

2. Cari resource ApName pada bagian atas halaman, dan ubah nilainya menjadi “Hello, world!”.

<x:String x:Key="AppName">Hello, World!</x:String>

3. Pada root Grid, sebelum tag <VisualStateManager.VisualStateGroups> tambahkan sebuah StackPanel dengan TextBlock untuk meminta nama pada pengguna, dan sebuah TextBox untuk menerima masukan pengguna, sebuah Button. Penjelasan kontrol yang digunakan akan dijelaskan kemudian. Listing kode nya adalah sebagai berikut :


<StackPanel Grid.Row="1" Margin="120,30,0,0">

<TextBlock Text="What's your name?"/>

<StackPanel Orientation="Horizontal" Margin="0,20,0,20">

<TextBox x:Name="nameInput"

Width="300" HorizontalAlignment="Left"/>

<Button Content="say hello"/>

</StackPanel>

<TextBlock x:Name="greetingOutput"/>

</StackPanel>

4. Pilih Button yang sudah ditambahkan di MainPage.xaml

5. Pada jendela Properties, pilih tombol Events (disebelah kanan pojok atas, yang menyerupai petir), pilih event Click dan tempatkan sebuah nama fungsi yang akan dipanggil,ketika Button tersebut diklik. Pada contoh ini, berikan nama Button_Click

6. Tambahkan kode berikut ini di berkas kode sumber untuk halaman tersebut. Event handler adalah mekanisme memberikan sebuah aksi yang akan dilakukan aplikasi terkait dengan event yang dibangkitkan oleh pengguna,dalam contoh ini adalah meng-klik Button.

private void Button_Click(object sender, RoutedEventArgs e)

{

greetingOutput.Text = “Hello, ” + nameInput.Text + “!”;

}

7. Tekan F5 dan jalankan aplikasi. Ketikkan nama Anda dan klik Button untuk menampilkan hasilnya.

Selamat, pada tahap ini , Anda sudah berhasil membuat aplikasi Windows 8-style UI pertama Anda J . Nah, sebelum membahas lebih dalam mengenai konsep-konsep baru pada pengembangan aplikasi Windows 8-style UI, pada bagian-bagian selanjutnya kita akan berkenalan dengan hal-hal mendasar yang baru dan wajib diketahui pemrogram yang sudah biasa dengan dunia .NET seperti Visual Studio 2012, XAML, pemrograman asinkronus dan kontrol-kontrol yang dapat digunakan untuk membangun antarmuka aplikasi.

Developer License

Apabila Anda menggunakan Visual Studio untuk pertama kalinya maka Visual Studio akan meminta developer license ketika kita ingin mengembangkan aplikasi Windows 8-style UI. License ini diperoleh secara gratis,pastikan komputer Anda terhubung ke internet dan masukkan akun Windows Live Anda dan license akan diperoleh.

Motivasi Berprestasi

Saya teringat dengan salah satu mata kuliah yang pernah saya ambil jaman masih kuliah di Institut Teknologi di Bandung. Nama mata kuliahnya motivasi berprestasi. Kenapa saya teringat kuliah ini ? Beberapa hari yang ada status seseorang yang intinya sedang ‘bercermin’ kembali dengan apa yang sudah dilakukannya selama ini. Apakah sudah memenuhi keinginan dan kebutuhan dirinya ? Memang, bercermin harus selalu kita lakukan untuk menjadi pribadi yang lebih baik. Katanya,kalau mau bersyukur lihatlah ke bawah, kalau mau termotivasi, lihatlah ke atas (dibaca secara konotasi).

Berbicara tentang kebutuhan dan keinginan dalam hidup, ada suatu teori yang terkenal di dunia psikologi, yang diajarkan pada kuliah Motivasi Berprestasi tersebut, yaitu Teori Kebutuhan-nya Abraham Maslow.

Maslow membagi kebutuhan manusia menjadi lima tahap, seperti gambar piramida di atas. Yang pertama adalah level fisiologi, yaitu kebutuhan untuk makan, air, eksekrasi, bernapas, tidur, dst. Selanjutnya, adalah level safety, keamanan dari sisi kesehatan, keamaan pekerjaan, sumber daya, properti dst. Level berikutnya adalah level psikologi, seperti pertemanan, keluarga, dan intimasi dengan pasangan. Level diatasnya, esteem, adalah kebutuhan untuk kepercayaan diri, pencapaian, respek dari orang lain. Level yang paling atas, aktualisasi adalah kebutuhan untuk menyelesaikan masalah, fokus pada sekitar, moreal dan kreativitas.

Menurut Maslow, orang-orang pada negara maju lebih fokus ke level love/belonging dan esteem, sementara orang-orang pada negara berkembang masih fokus ke level fisiologi dan safety. Piramida kebutuhan ini mengisyaratkan suatu kebutuhan (yang akhirnya mendorong aksi dari seseorang) akan muncul setelah kebutuhan pada tahap dibawahnya terpenuhi. Contoh mudahnya, orang tidak akan butuh respek dari orang lain atau ingin suatu pencapaian jika untuk makan saja masih susah. Atau orang tidak akan kepikiran untuk mencari respek orang lain, jika pekerjaan atau kesehatan saja belum stabil. Kebutuhan tersebut hanya muncul jika kebutuhan pada level sebelumnya terpenuhi. Saya tidak yakin Bill Gates akan melakukan seluruh hal filantropi yang dilakukannya saat ini jika dia merasa kebutuhannya belum tercukupi. Dia bisa bermimpi untuk dunia yang lebih sehat, dunia yang sembuh dengan vaksin, dunia butuh toilet yang lebih baik karena kebutuhan seperti fisiologi,safety,love sudah dia miliki. Saya tidak yakin Ciputra akan punya mimpi besar untuk Indonesia yang lebih baik dengan enterpreneurship jika kebutuhan level fisiologi safety dan love-nya belum terpenuhi. Karenanya, sangatlah sulit membandingkan diri kita dengan orang lain misalnya, jika pemenuhan kebutuhannya belum pada level yang sama.

Bercermin ke atas itu perlu, ke bawah itu juga perlu. Tapi jangan dijadikan sebuah keharusan atau panduan yang bersifat tetap. Takutnya malah jadi destruktif. Bercermin pada diri sendiri menurut saya lebih baik. Memenuhi kebutuhan itu satu hal. Menjadi bahagia itu satu hal. Kata rekan saya, orang kaya dan tukang sapu bisa sama-sama bahagia walaupun kalo kita liat dari sisi Maslow, level pemenuhan kebutuhannya saja sudah berbeda. Penuhi kebutuhanmu dan berusahalah menjadi bahagia Smile.