0

[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 _tableSource thành protected.
/*private*/ protected ObservableTableSource<T> _tableSource;
  • Đổi phương thức BindCell thành public.
/*protected*/ public virtual void BindCell(UITableViewCell cell,
                                           object item,
                                           NSIndexPath indexPath)
  • Đổi phương thức CreateCell thành public
/*protected*/ public virtual UITableViewCell CreateCell(NSString reuseId)
  • Đổi phương thức OnRowSelected thành public
/*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 _controller thành public
/*private*/ protected readonly ObservableTableViewController<T2> _controller;
  • Đổi phương thức GetCell sử 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 RowSelected sử 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 RowsInSection sử 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, CommitEditingStyleEditingStyleForRow để 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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí