-
-
Save Clancey/0a0ea640794da5a10070 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Specialized; | |
using System.Diagnostics; | |
using MonoTouch.Foundation; | |
using MonoTouch.UIKit; | |
namespace Praeclarum.UI | |
{ | |
[Register ("ObservableTableView")] | |
public class ObservableTableView : UITableView | |
{ | |
public UITableViewRowAnimation AddAnimation { get; set; } | |
public UITableViewRowAnimation DeleteAnimation { get; set; } | |
object dataSource; | |
IList list; | |
INotifyCollectionChanged notifier; | |
System.Threading.Thread mainThread; | |
bool loadedView = false; | |
public string CellIdentifier = "C"; | |
public bool UnEvenRows{get;set;} | |
public object DataSource { | |
get { | |
return dataSource; | |
} | |
set { | |
if (dataSource == value) | |
return; | |
if (notifier != null) { | |
notifier.CollectionChanged -= HandleCollectionChanged; | |
} | |
dataSource = value; | |
list = value as IList; | |
notifier = value as INotifyCollectionChanged; | |
if (notifier != null) { | |
notifier.CollectionChanged += HandleCollectionChanged; | |
} | |
if (loadedView) { | |
this.ReloadData (); | |
} | |
} | |
} | |
public ObservableTableView () | |
: this (UITableViewStyle.Plain) | |
{ | |
Initialize (); | |
} | |
public ObservableTableView (UITableViewStyle withStyle) | |
: base (RectangleF.Empty,withStyle) | |
{ | |
Initialize (); | |
} | |
void Initialize () | |
{ | |
mainThread = System.Threading.Thread.CurrentThread; | |
AddAnimation = UITableViewRowAnimation.Automatic; | |
DeleteAnimation = UITableViewRowAnimation.Automatic; | |
Source = CreateSource (); | |
loadedView = true; | |
} | |
protected virtual ObservableTableSource CreateSource () | |
{ | |
return new ObservableTableSource (this); | |
} | |
protected virtual UITableViewCell CreateCell (string reuseId) | |
{ | |
return new UITableViewCell (UITableViewCellStyle.Default, reuseId); | |
} | |
protected virtual UIView CreateHeader () | |
{ | |
return null; | |
} | |
protected virtual void BindCell (UITableViewCell cell, object item, NSIndexPath indexPath) | |
{ | |
cell.TextLabel.Text = item.ToString (); | |
} | |
protected virtual void OnRowSelected (object item, NSIndexPath indexPath) | |
{ | |
} | |
protected virtual UITableViewCellEditingStyle EditingStyleForRow (NSIndexPath indexPath) | |
{ | |
return UITableViewCellEditingStyle.Delete; | |
} | |
void HandleCollectionChanged (object sender, NotifyCollectionChangedEventArgs e) | |
{ | |
if (!loadedView) | |
return; | |
NSAction act = () => { | |
if (e.Action == NotifyCollectionChangedAction.Reset) { | |
this.ReloadData (); | |
} | |
if (e.Action == NotifyCollectionChangedAction.Add) { | |
var count = e.NewItems.Count; | |
var paths = new NSIndexPath[count]; | |
for (var i = 0; i < count; i++) { | |
paths [i] = NSIndexPath.FromRowSection (e.NewStartingIndex + i, 0); | |
} | |
this.InsertRows (paths, AddAnimation); | |
} else if (e.Action == NotifyCollectionChangedAction.Remove) { | |
var count = e.OldItems.Count; | |
var paths = new NSIndexPath[count]; | |
for (var i = 0; i < count; i++) { | |
paths [i] = NSIndexPath.FromRowSection (e.OldStartingIndex + i, 0); | |
} | |
this.DeleteRows (paths, DeleteAnimation); | |
} | |
}; | |
var isMainThread = System.Threading.Thread.CurrentThread == mainThread; | |
if (isMainThread) { | |
act (); | |
} else { | |
NSOperationQueue.MainQueue.AddOperation (act); | |
NSOperationQueue.MainQueue.WaitUntilAllOperationsAreFinished (); | |
} | |
} | |
protected class ObservableTableSource : UITableViewSource | |
{ | |
readonly ObservableTableView controller; | |
public ObservableTableSource (ObservableTableView controller) | |
{ | |
this.controller = controller; | |
} | |
public override void RowSelected (UITableView tableView, NSIndexPath indexPath) | |
{ | |
var item = controller.list != null ? controller.list [indexPath.Row] : null; | |
try { | |
controller.OnRowSelected (item, indexPath); | |
} catch (Exception ex) { | |
Debug.WriteLine (ex); | |
} | |
} | |
public override int NumberOfSections (UITableView tableView) | |
{ | |
return 1; | |
} | |
public override int RowsInSection (UITableView tableview, int section) | |
{ | |
var coll = controller.list; | |
return coll != null ? coll.Count : 0; | |
} | |
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) | |
{ | |
var cell = tableView.DequeueReusableCell (controller.CellIdentifier) ?? | |
controller.CreateCell (controller.CellIdentifier); | |
try { | |
var coll = controller.list; | |
if (coll != null) { | |
var obj = coll[indexPath.Row]; | |
controller.BindCell (cell, obj, indexPath); | |
} | |
return cell; | |
} | |
catch (Exception ex) { | |
Debug.WriteLine (ex); | |
} | |
return cell; | |
} | |
public override UITableViewCellEditingStyle EditingStyleForRow (UITableView tableView, NSIndexPath indexPath) | |
{ | |
try{ | |
return controller.EditingStyleForRow(indexPath); | |
} | |
catch(Exception ex) { | |
Debug.WriteLine (ex); | |
} | |
return UITableViewCellEditingStyle.Delete; | |
} | |
public override void CommitEditingStyle (UITableView tableView, UITableViewCellEditingStyle editingStyle, NSIndexPath indexPath) | |
{ | |
controller.list.RemoveAt (indexPath.Row); | |
} | |
public override bool RespondsToSelector (MonoTouch.ObjCRuntime.Selector sel) | |
{ | |
if (sel.Name == "tableView:viewForHeaderInSection:") { | |
return controller.CreateHeader() != null; | |
} | |
return base.RespondsToSelector (sel); | |
} | |
public override UIView GetViewForHeader (UITableView tableView, int section) | |
{ | |
return controller.CreateHeader (); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment