[Xamarin.iOS] Tìm hiểu sâu hơn về Table View trong MVVM Light
Tiếp tục bài viết trước [Xamarin.iOS] Sử dụng Table View trong MVVM Light.
Overview
Trong phần này, chúng ta sẽ tìm hiểu sâu hơn một chút về cách sử dụng MVVM Light với Xamarin iOS TableViews, cụ thể chúng ta sẽ tuỳ chỉnh cho TableView có thể swipe để xoá item.
Example Step by Step
Chúng ta sẽ mở rộng thêm tính năng Swipe to Delete cho ứng dụng đã làm ở bài viết trước
Vẫn sử dụng source code ở bài viết trước.
Download MVVM Light source code về, giải nén và copy ObservableTableViewController class trong thư mục Galasoft.MvvmLight.Platform (iOS)/Helpers vào ObservableTables.iOS project. Trong file class ObservableTableViewController tìm và chuyển class ObservableTableSource ra thành 1 file riêng.
Sửa lại ObservableTableViewController class với những thay đổi như sau:
- Đổi
_tableSourcethànhprotected.
/*private*/ protected ObservableTableSource<T> _tableSource;
- Đổi phương thức
BindCellthànhpublic.
/*protected*/ public virtual void BindCell(UITableViewCell cell,
object item,
NSIndexPath indexPath)
- Đổi phương thức
CreateCellthànhpublic
/*protected*/ public virtual UITableViewCell CreateCell(NSString reuseId)
- Đổi phương thức
OnRowSelectedthànhpublic
/*protected*/ public virtual void OnRowSelected(object item,
NSIndexPath indexPath)
Sửa lại ObservableTableSource class với những thay đổi như sau:
- Đổi class thành
public
/*protected*/ public class ObservableTableSource<T2> : UITableViewSource
- Đổi
_controllerthànhpublic
/*private*/ protected readonly ObservableTableViewController<T2> _controller;
- Đổi phương thức
GetCellsử dụng DataSource property
public override UITableViewCell GetCell(UITableView tableView,
NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell(_reuseId) ??
_controller.CreateCell(_reuseId);
try
{
//var coll = _controller._dataSource;
var coll = _controller.DataSource;
- Đổi phương thức
RowSelectedsử dụng DataSource property
public override void RowSelected(UITableView tableView,
NSIndexPath indexPath)
{
//var item = _controller._dataSource != null ?
_controller._dataSource[indexPath.Row] : default(T2);
var item = _controller.DataSource != null ?
_controller.DataSource[indexPath.Row] : default(T2);
- Đổi phương thức
RowsInSectionsử dụng DataSource property
public override nint RowsInSection(UITableView tableView,
nint section)
{
//var coll = _controller._dataSource;
var coll = _controller.DataSource;
Tạo một class TaskListObservableTableSource derives từ ObservableTableSource và override các phương thức CanEditRow, CommitEditingStyle và EditingStyleForRow để thực hiện chức năng swipe để xoá
using System;
using UIKit;
using Foundation;
namespace ObservableTables.iOS
{
public class TaskListObservableTableSource<T> :
ObservableTableSource<T>
{
public TaskListObservableTableSource(
ObservableTableViewController<T> controller)
: base(controller)
{
}
public override bool CanEditRow(UITableView tableView,
NSIndexPath indexPath)
{
return true;
}
public override void CommitEditingStyle(UITableView tableView,
UITableViewCellEditingStyle editingStyle,
NSIndexPath indexPath)
{
switch (editingStyle)
{
case UITableViewCellEditingStyle.Delete:
// remove the item from the underlying data source
_controller.DataSource.RemoveAt(indexPath.Row);
// No need to delete the row from the table as the tableview
// is bound to the data source
break;
}
}
public override UITableViewCellEditingStyle EditingStyleForRow(
UITableView tableView,
NSIndexPath indexPath)
{
return UITableViewCellEditingStyle.Delete;
}
}
}
Tiếp theo, tạo một calss TaskListObservableTableViewControllerderives từ ObservableTableViewController. Class này sẽ override phương thức CreateSource để tạo ra instance mới của TaskListObservableTableSource.
using UIKit;
namespace ObservableTables.iOS
{
public class TaskListObservableTableViewController<T> :
ObservableTableViewController<T>
{
public TaskListObservableTableViewController()
: base()
{
}
public TaskListObservableTableViewController(
UITableViewStyle tableStyle)
: base(tableStyle)
{
}
protected override ObservableTableSource<T> CreateSource()
{
_tableSource = new TaskListObservableTableSource<T>(this);
return _tableSource;
}
}
}
Tạo một static extensions class ExtensionsMvvmLight và phương thứcGetTaskListController dựa vào phương thức GetController trong class Galasoft.MvvmLight.Platform (iOS)/Helpers/ExtensionsApple. Phương thức này được gọi trong TaskListViewController để tạo TaskListObservableViewControlle
using System;
using System.Collections.Generic;
using Foundation;
using UIKit;
namespace ObservableTables.iOS
{
public static class ExtensionsMvvmLight
{
public static TaskListObservableTableViewController<T>
GetTaskListController<T>(
this IList<T> list,
Func<NSString, UITableViewCell> createCellDelegate,
Action<UITableViewCell, T, NSIndexPath> bindCellDelegate)
{
return new TaskListObservableTableViewController<T>
{
DataSource = list,
CreateCellDelegate = createCellDelegate,
BindCellDelegate = bindCellDelegate
};
}
}
}
Mở TaskListViewController class, sửa private ObservableTableViewController<TaskModel> tableViewController; thành private TaskListObservableTableViewController<TaskModel> tableViewController; và gọi GetTaskListController trong phương thức ViewDidLoad
using Foundation;
using System;
using UIKit;
using GalaSoft.MvvmLight.Helpers;
using ObservableTables.ViewModel;
namespace ObservableTables.iOS
{
partial class TaskListViewController : UIViewController
{
private TaskListObservableTableViewController<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.GetTaskListController(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;
}
}
}
Xong, như vậy là đã hoàn thành, bây giờ ta đã có thể swipe để xoá item trong TableView.
All rights reserved