[Xamarin.iOS] Sử dụng Table View trong MVVM Light
Mục đích bài viết mình muốn giới thiệu mọi người cách sử dụng Table View trong MVVM Light, cách dùng ObservableTableViewController để có thể tự động binding dữ liệu từ ViewModel lên View. Đơn giản chỉ cần 2 dòng code để tạo ObservableTableViewController và thiết lập TableView, 2 phương thức để khởi tạo Cell và bind giá trị cho Cell
public override void ViewDidLoad()
{
base.ViewDidLoad();
tableViewController = Vm.TodoTasks.GetController(CreateTaskCell, BindTaskCell);
tableViewController.TableView = TasksTableView;
}
private void BindTaskCell(UITableViewCell cell, TaskModel taskModel, NSIndexPath path)
{
cell.TextLabel.Text = taskModel.Name;
cell.DetailTextLabel.Text = taskModel.Notes;
}
private UITableViewCell CreateTaskCell(NSString cellIdentifier)
{
var cell = new UITableViewCell(UITableViewCellStyle.Subtitle, null);
cell.TextLabel.TextColor = UIColor.FromRGB(55, 63, 255);
cell.DetailTextLabel.LineBreakMode = UILineBreakMode.TailTruncation;
return cell;
}
Example Step by Step
Trong Example này ta có 1 màn hình hiển thị danh sách các Task đã được tạo, và nút Add(+) trên NavigationBar để thêm 1 task mới.

Đầu tiên chúng ta tạo một Single View App.

Và đặt tên là ObservableTables.

Next và tiếp tục config

Sau khi tạo project xong ta sẽ có cấu trúc solution như hình bên dưới

Tiếp theo chúng ta add MVMV Light Nuget package cho ObservableTable.iOS project.

Add Nutget package MVVM Light Library Only cho ObservableTable project

Tiếp theo chúng ta xoá class MyClass trong ObservableTable đi
Tạo 1 thư mục Models và class TaskModel bên trong nó
Trong class TaskModel.cs
Xoá dòng này
using System;
Thêm vào dòng này
using GalaSoft.MvvmLight;
Sửa lại nội dung class TaskModel.cs như bên dưới
public class TaskModel :ObservableObject
{
public TaskModel()
{
}
public int ID { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public bool Done { get; set; }
}
Sau khi add MVMV Light Nuget package cho ObservableTable.iOS project thì nó sẽ tự đông generate ra thư mục ViewModel và 2 class ViewModelLocator và MainViewModel. Di chuyển chúng qua ObservableTable project.
Thay đổi namespace 2 class trên thành ObservableTables.ViewModel.
Sửa tên MainViewModel class thành TaskListViewModel.
Sửa lại nội dung class TaskListViewModel:
public class TaskListViewModel : ViewModelBase
{
public ObservableCollection<TaskModel> TodoTasks { get; private set; }
public TaskListViewModel()
{
TodoTasks = new ObservableCollection<TaskModel>()
{
new TaskModel
{
Name = "Make Lunch",
Notes = ""
},
new TaskModel
{
Name = "Pack Lunch",
Notes = "In the bag, make sure we don't squash anything."
},
new TaskModel
{
Name = "Goto Work",
Notes = "Walk if it's sunny"
},
new TaskModel
{
Name = "Eat Lunch",
Notes = ""
}
};
AddTaskCommand = new RelayCommand(AddTask);
}
public RelayCommand AddTaskCommand { get; set; }
private void AddTask()
{
TodoTasks.Add(new TaskModel
{
Name = "New Task",
Notes = ""
});
}
}
Sửa lại phần using ở class ViewModelLocator:
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
Sửa lại đăng ký class TaskListViewModel trong ViewModelLocator vì trước đó ta đã thay đổi tên class
public class ViewModelLocator
{
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<TaskListViewModel>();
}
public TaskListViewModel TaskList
{
get
{
return ServiceLocator.Current.GetInstance<TaskListViewModel>();
}
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
Quay lại ObservableTables.iOS project
Xoá class ViewController.
Tạo 1 View Controller mới và đặt tên là TaskListViewController
Nội dung class sẽ như thế này:
using Foundation;
using System;
using UIKit;
using GalaSoft.MvvmLight.Helpers;
using ObservableTables.ViewModel;
partial class TaskListViewController : UIViewController
{
private ObservableTableViewController<TaskModel> tableViewController;
private TaskListViewModel Vm => Application.Locator.TaskList;
public TaskListViewController(IntPtr handle) : base (handle)
{
}
public UIBarButtonItem AddTaskButton
{
get;
private set;
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
AddTaskButton = new UIBarButtonItem(UIBarButtonSystemItem.Add);
this.NavigationItem.SetLeftBarButtonItem(AddTaskButton, false);
//note this was needed when deploying to a real iPhone but worked
//on the simulator without it.
//The Argument Exception Event not found clicked was thrown
AddTaskButton.Clicked += (sender, e) => {};
AddTaskButton.SetCommand("Clicked", Vm.AddTaskCommand);
tableViewController = Vm.TodoTasks.GetController(CreateTaskCell, BindTaskCell);
tableViewController.TableView = TasksTableView;
}
private void BindTaskCell(UITableViewCell cell, TaskModel taskModel, NSIndexPath path)
{
cell.TextLabel.Text = taskModel.Name;
cell.DetailTextLabel.Text = taskModel.Notes;
}
private UITableViewCell CreateTaskCell(NSString cellIdentifier)
{
var cell = new UITableViewCell(UITableViewCellStyle.Subtitle, null);
cell.TextLabel.TextColor = UIColor.FromRGB(55, 63, 255);
cell.DetailTextLabel.LineBreakMode = UILineBreakMode.TailTruncation;
return cell;
}
}
Mở Main.storyboard lên

Xoá View Controller hiện tại đi

Ở Toolbox, chọn Navigation Controller và kéo nó vào

Select icon View Controller màu vàng ở thanh màu đen bên dưới, ở cửa sổ Properties nhập Name là TaskListViewController

Trong Document Outline, chọn navigation item, edit Title thành Tasks

Chọn Table View ở Toolbox và kéo nó vào TaskListViewController và đặt tên là TasksTableView

Chỉnh lại kích thước của Table View

Bây giờ chúng ta mở Main class ra, và sửa lại như bên dưới:
using UIKit;
using ObservableTables.ViewModel;
namespace ObservableTables.iOS
{
public class Application
{
private static ViewModelLocator locator;
// This is the main entry point of the application.
static void Main (string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main (args, null, "AppDelegate");
}
public static ViewModelLocator Locator
{
get
{
return locator ?? (locator = new ViewModelLocator());
}
}
}
}
Trong AppDelegate, ta thêm đoạn code khởi tạo Mvvm Light DispatcherHelper trong FinishedLaunching method
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
// Override point for customization after application launch.
// If not required for your application you can safely delete this method
// MVVM Light's DispatcherHelper for cross-thread handling.
DispatcherHelper.Initialize(application);
return true;
}
Như vậy là đã hoàn thành phần code, bây giờ bạn có thể chạy thử để xem kết quả.
Bài viết còn nhiều thiếu sót, rất mong mọi người góp ý.
All rights reserved