WPF (Windows Presentation Foundation) merupakan sebuah subsistem grafis yang dikembangkan Microsoft untuk membangun aplikasi GUI pada sistem operasi Windows. Tulisan ini akan membahas bagaimana cara membuat aplikasi yang memiliki beberapa halaman, di mana pada setiap halamannya terdapat isi yang berbeda-beda (seperti pada sebuah website).

Untuk menajamkan fokus, pembahasan hanya dilakukan sebatas contoh konsep, dengan kode yang sangat tidak siap untuk digunakan pada lingkungan produksi. Jika terdapat kode yang tidak optimal, catatan akan diberikan kepada pembaca, dengan petunjuk ke arah yang tepat bagaimana kode yang siap digunakan pada lingkungan produksi seharusnya.

Catatan: Kode keseluruhan dari proyek dapat diambil dari repository Github berikut. Karena sifat tulisan yang konseptual, akan jauh lebih mudah jika pembaca langsung membuka kode dan melihat cara kerja aplikasi dibandingkan dengan membaca keseluruhan tulisan terlebih dahulu.

Multi-Halaman?

Aplikasi WPF (dan aplikasi pada Windows umumnya) biasanya memiliki beberapa jendela atau Form, yang ditampilkan ketika pengguna membuka sebuah menu atau melakukan sesuatu pada aplikasi. Pengembangan umumnya dilakukan menggunakan banyak Form atau Window, dan setiap kali pengguna berganti tampilan dalam aplikasi, pengguna disajikan kepada Form atau Window yang berbeda. Tetapi terkadang kita ingin memberikan hanya satu Window saja kepada pengguna, dan jika diperlukan perubahan konten, pengguna akan langsung mendapatkan perubahan tersebut, tanpa harus menunggu aplikasi berganti jendela. Bagaimana caranya?

Rancangan Halaman

Yang pertama kali harus kita lakukan ialah membuat halaman utama pada aplikasi WPF sebagai halaman kosong, yang tidak memiliki isi apa-apa. Buat Proyek WPF baru, dan pastikan kode pada halaman utama (yang secara otomatis dibuat ketika membuat proyek baru) tidak memiliki isi, seperti berikut:

<Window x:Class="WPFMultiPage.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPF Multi Page" Height="600" Width="800" ResizeMode="NoResize">
</Window>

Perhatikan bahwa tidak terdapat elemen <Grid> ataupun elemen-elemen lain di dalam elemen <Window>. Kita hanya mengubah atribut dari elemen ini, kemudian menutup elemen.

Buat sebuah halaman baru, dengan nama MainPage.xaml, dengan melakukan klik kanan pada Solution dan kemudian masuk ke menu Add -> Page. Untuk merapikan kode, masukkan halaman baru tersebut ke dalam direktori Page, yang dapat dibuat dengan memasuki menu Add -> New Folder. Perhatikan gambar di bawah jika kurang jelas:

Pembuatan Halaman dan Folder Baru

Dan kemudian rancang antarmuka MainPage.xaml sesuai dengan isi yang diinginkan. Pada contoh ini hanya akan dibuat sebuah label dan tombol untuk berpindah halaman.

Rancangan Halaman Utama

Pastikan kode pada jendela utama langsung menampilkan halaman utama, dengan menggantikan kode pada constructor seperti berikut:

// usings standard ...

using WPFMultiPage.Pages;

namespace WPFMultiPage
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Content = new MainPage();
        }
    }
}

Sampai titik ini, jika aplikasi dijalankan seharusnya kita sudah dapat melihat jendela utama dari aplikasi:

jendela utama

Tambahkan juga halaman Login, yang akan ditampilkan ketika tombol “Halaman Login” pada halaman utama ditekan. Halaman login cukup sederhana saja, hanya berupa tulisan dan tombol-tombol untuk berpindah ke halaman utama dan halaman lain lagi.

halaman login

Perpindahan Halaman

Persiapkan dua interface, yaitu INavigator dan INavigatable. INavigator merupakan interface yang memberikan fasilitas untuk berpindah halaman kepada sebuah Page atau class, sementara INavigatable memberikan fasilitas untuk menerima state. State pada aplikasi dapat digunakan untuk menyimpan berbagai data statis, seperti status autentikasi pengguna ataupun keberhasilan proses sebuah data.

Berikut adalah kode dari kedua interface tersebut (yang tentunya disimpan ke dalam file yang berbeda, masing-masing INavigator.cs dan INavigatable.cs):

interface INavigator
{
    void Navigate(Page nextPage, object state);
    void Navigate(Page nextPage);
}

interface INavigatable
{
    void ProcessState(object state);
}

Implementasi kedua interface tersebut kemudian dapat dilakukan pada halaman-halaman yang ada, misalnya pada MainPage:

// standard usings...

namespace WPFMultiPage.Pages
{
    /// <summary>
    /// Interaction logic for MainPage.xaml
    /// </summary>
    public partial class MainPage : Page, INavigatable, INavigator
    {
        public MainPage()
        {
            InitializeComponent();
        }

        public void Navigate(Page nextPage, object state)
        {
            Window.GetWindow(this).Content = nextPage;
            INavigatable n = nextPage as INavigatable;

            if (n != null)
            {
                n.ProcessState(state);
            }
            else
            {
                throw new ArgumentException("Halaman " + nextPage.Name + " tidak memiliki state!");
            }
        }

        public void Navigate(Page nextPage)
        {
            Window.GetWindow(this).Content = nextPage;
        }

        public void ProcessState(object state)
        {
            throw new NotImplementedException();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            Navigate(new LoginPage());
        }
    }
}

Perpindahan halaman pada MainPage dilakukan melalui fungsi yang dijalankan ketika tombol ditekan:

private void button1_Click(object sender, RoutedEventArgs e)
{
    Navigate(new LoginPage());
}

Ketika klik dilakukan, maka perpindahan halaman akan terjadi (dari halaman MainPage ke halaman Login). Perhatikan bahwa pada fungsi button1_Click, fungsi Navigate membuat objek LoginPage baru. Hal ini tentunya tidak optimal, karena terjadi pembuatan objek baru pada setiap perubahan halaman. Idelnya, kita harus memiliki sebuah objek yang mengontrol pembuatan halaman secara keseluruhan, dan objek ini juga mengatur navigasi dari keseluruhan aplikasi. Jadi, idealnya hanya terdapat satu INavigator dan banyak INavigatable pada aplikasi yang berjalan di lingkungan produksi (perhatikan bagaimana dalam kode yang ada dalam repository, terdapat duplikasi pada setiap implementasi INavigator. Hal ini tentunya juga sangat tidak baik).

Implementasi keseluruhan kode dapat diakses di repository Github berikut, dan penambahan animasi serta implementasi lingkungan produksi diserahkan ke pembaca.

comments powered by Disqus

Daftar Isi