[Xamarin Forms Series] – Menggunakan Library MVVM Helper – Part 2

Tutorial berikut adalah lanjutan dari tutorial MVVM dengan Xamarin Forms 5 yang sudah ditulis sebelumnya.

Untuk mempermudah penggunaan MVVM di Xamarin, anda dapat menggunakan library MVVMHelper. Library ini mendukung beberapa fitur yang sangat membantu kita dalam mengimplementasikan pola MVVM. Fitur-fitur tersebut diantarannya ViewModelBase, AsyncCommand dan ObservableRangeCollection.

Untuk menambahkan library MVVMHelper pada solution, tambahkan package manager berikut ini. Klik kanan pada solution, kemudian cari library MVVMHelpers

Setelah itu buat class dengan nama ViewModelBase yang diturunkan dari class BaseViewModel yang ada pada MVVMHelper.

    public class ViewModelBase : BaseViewModel
    {
    }

Kemudian buat class dengan nama CoffeeEquipmentViewModel.cs pada folder ViewModel. Disini kita akan menambahkan o ObservableRange yang akan digunakan sebagai sumber data pada ListView.

namespace MyXamarinApps.ViewModels
{
    public class CoffeeEquipmentViewModel : ViewModelBase
    {
        public ObservableRangeCollection<string> Coffee { get; set; }

        public ICommand IncreaseCount { get; }

        public ICommand CallServerCommand { get;}

        public CoffeeEquipmentViewModel()
        {
            IncreaseCount = new Command(OnIncrease);
            CallServerCommand = new AsyncCommand(CallServer);
            Coffee = new ObservableRangeCollection<string>();
            Title = "Coffee Equipment";
        }

        async Task CallServer()
        {
            var items = new List<string> { "Luwak Coffee", "Aceh Gayo", "Toraja Coffee" };
            Coffee.AddRange(items);
        }

        int count = 0;
        private string countDisplay = "Click Me";
        public string CountDisplay
        {
            get => countDisplay;
            set => SetProperty(ref countDisplay, value);
        }

        private void OnIncrease()
        {
            count++;
            CountDisplay = $"You clicked {count} time";
        }
    }
}

Tambahkan class Coffee di folder Model.

    public class Coffee
    {
        public string Roaster { get; set; }
        public string Name { get; set; }
        public string Image { get; set; }
    }

Kemudian modifikasi class CoffeeEquipmentViewModel

namespace MyXamarinApps.ViewModels
{
    public class CoffeeEquipmentViewModel:ViewModelBase
    {
        public ObservableRangeCollection<Coffee> Coffee { get; set; }
        public ObservableRangeCollection<Grouping<string,Coffee>> CoffeeGroup { get; set; }
        public AsyncCommand RefreshCommand { get; }
        public AsyncCommand<Coffee> FavoriteCommand { get; set; }
        public AsyncCommand<object> SelectedCommand { get; set; }

        public CoffeeEquipmentViewModel()
        {
            Title = "Coffee Equipment";
            Coffee = new ObservableRangeCollection<Coffee>();
            CoffeeGroup = new ObservableRangeCollection<Grouping<string, Coffee>>();
            var image = "luwak.png";

            Coffee.Add(new Coffee { Roaster = "Otten Coffee", Name = "Italian Roasted", Image = image });
            Coffee.Add(new Coffee { Roaster = "Blue Bottle", Name = "Aceh Gayo", Image = image });
            Coffee.Add(new Coffee { Roaster = "Blue Bottle", Name = "Darked Roasted", Image = image });
            Coffee.Add(new Coffee { Roaster = "Otten Coffee", Name = "Kenya Kiambu", Image = image });
            Coffee.Add(new Coffee { Roaster = "Yes Plz", Name = "Pike Market", Image = image });
            Coffee.Add(new Coffee { Roaster = "Otten Coffee", Name = "Toraja", Image = image });

            CoffeeGroup.Add(new Grouping<string, Coffee>("Otten Coffee",Coffee.Where(c=>c.Roaster== "Otten Coffee")));
            CoffeeGroup.Add(new Grouping<string, Coffee>("Blue Bottle", Coffee.Where(c => c.Roaster == "Blue Bottle")));
            
            RefreshCommand = new AsyncCommand(Refresh);
            FavoriteCommand = new AsyncCommand<Coffee>(Favorite);
            SelectedCommand = new AsyncCommand<object>(SelectedCoffee);
        }

        private async Task SelectedCoffee(object arg)
        {
            var coffee = arg as Coffee;
            if (coffee == null) return;
            await Application.Current.MainPage.DisplayAlert("Selected", coffee.Name, "OK");
        }

        private async Task Favorite(Coffee coffee)
        {
            if (coffee == null)
                return;
            await Application.Current.MainPage.DisplayAlert("Favorite", $"{coffee.Roaster} - {coffee.Name}", "OK");
        }

        private async Task Refresh()
        {
            IsBusy = true;
            await Task.Delay(2000);
            IsBusy = false;
        }
    }
}

Pada XAML tambahkan kode berikut untuk membinding objek ViewModel yang sudah kita buat sebelumnya.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:viewmodels="clr-namespace:SampleMVVM.ViewModels"
             x:Class="MyXamarinApps.ViewModels">

    <ContentPage.BindingContext>
        <viewmodels:CoffeeEquipmentViewModel />
    </ContentPage.BindingContext>

    <ListView BackgroundColor="Transparent" 
              ItemsSource="{Binding Coffee}"
              HasUnevenRows="True"
              SeparatorVisibility="None">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ViewCell.ContextActions>
                        <MenuItem Text="Favorite" />
                        <MenuItem IsDestructive="True" Text="Delete" />
                    </ViewCell.ContextActions>
                    <Grid Padding="10">
                        <Frame CornerRadius="20" HasShadow="True">
                            <StackLayout Orientation="Horizontal">
                                <Image Source="{Binding Image}" WidthRequest="66" />
                                <StackLayout VerticalOptions="Center">
                                    <Label
                                        FontSize="Large"
                                        Text="{Binding Name}"
                                        VerticalOptions="Center" />
                                    <Label
                                        FontSize="Large"
                                        Text="{Binding Roaster}"
                                        VerticalOptions="Center" />
                                </StackLayout>
                            </StackLayout>
                        </Frame>
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.Header>
            <StackLayout Orientation="Horizontal">
                <Label HorizontalOptions="Center" Text="Coffee of the World" />
            </StackLayout>
        </ListView.Header>
        <ListView.Footer>
            <StackLayout HorizontalOptions="Center" Orientation="Horizontal">
                <Button Text="Load More" />
            </StackLayout>
        </ListView.Footer>
    </ListView>
</ContentPage>

Jalankan aplikasinya untuk melihat tampilan List yang mengambil data contoh dari ViewModel yang sudah dibuat sebelumnya. Dari contoh ini dapat dilihat bahwa dengan menggunakan MVVMHelper kita dapat menggunakan objek ObservableRange yang fleksible untuk digunakan sebagai tempat menampung objek bertipe List. Selain itu MVVMHelper juga mendukung AsyncCommand untuk membuat command yang mendukung async method.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s