/// A group that contains table items
/// </summary>
public class BasicTableViewItemGroup
{
public string Name { get; set; }
public string Footer { get; set; }
public List<BasicTableViewItem> Items
{
get { return this._items; }
set { this._items = value; }
}
protected List<BasicTableViewItem> _items = new List<BasicTableViewItem>();
public BasicTableViewItemGroup ()
{
}
}
//========================================================================
}
这也是一个相称复杂的类。它用于项目分组的容器。具有以下属性:
Name――分组的称号。一般显现在分组的顶部。
Footer――显现在以后组中一切项目标底部笔墨
Items――分组所包括的BasicTableViewItem的List汇合。我们在其机关的时分实例化这个汇合,以便在增加项目标时分无需手动往实例化它。
接着,再在统一个文件夹中创立别的一个类,定名为“BasicTableViewSource”,并输出以下代码:
using System;
using System.Collections.Generic;
using MonoTouch.UIKit;
public BasicTableViewSource (List<BasicTableViewItemGroup> items)
{
this._tableItems = items;
}
/// <summary>
/// Called by the TableView to determine how many sections(groups) there are.
/// </summary>
public override int NumberOfSections (UITableView tableView)
{
return this._tableItems.Count;
}
/// <summary>
/// Called by the TableView to determine how many cells to create for that particular section.
/// </summary>
public override int RowsInSection (UITableView tableview, int section)
{
return this._tableItems[section].Items.Count;
}
/// <summary>
/// Called by the TableView to retrieve the header text for the particular section(group)
/// </summary>
public override string TitleForHeader (UITableView tableView, int section)
{
return this._tableItems[section].Name;
}
/// <summary>
/// Called by the TableView to retrieve the footer text for the particular section(group)
/// </summary>
public override string TitleForFooter (UITableView tableView, int section)
{
return this._tableItems[section].Footer;
}
/// <summary>
/// Called by the TableView to get the actual UITableViewCell to render for the particular section and row
/// </summary>
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.FoundationNSIndexPath indexPath)
{
//---- declare vars
//---- if there are no cells to reuse, create a new one
if (cell == null)
{
cell = new UITableViewCell (UITableViewCellStyle.Default, this._cellIdentifier);
}
为了确保你之前的步骤都是准确的,能够经由过程编译项目来查验。要举行编译,按住AppleKey(苹果键),再按“B”键,大概从“Build”菜单当选择”BuildAll“。
统统一般的话,我们就筹办好了相干的类和图片。让我们来编纂使用程序代码以利用它们!
在Main.cs上双击,显现出代码编纂器。在AppDelegate类中,增加以下代码行:
BasicTableViewSource _tableViewSource;
ThisisaclassvariabletoholdourBasicTableViewSourcethatwecreatedearlier.
这是一个类变量,用来保留我们初期创立的BasicTableViewSource实例。
接着,把以下办法复制到AppDelegate类中:
/// <summary>
/// Creates a set of table items.
/// </summary>
protected void CreateTableItems ()
{
List<BasicTableViewItemGroup> tableItems = new List<BasicTableViewItemGroup> ();
//---- declare vars
BasicTableViewItemGroup tGroup;
//---- birds
tGroup = new BasicTableViewItemGroup() { Name = "Birds", Footer = "Birds have wings, and sometimes use them." };
tGroup.Items.Add (new BasicTableViewItem() { Name = "Crow", SubHeading = "AKA, Raven.", ImageName = "PawIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Chicken", SubHeading = "Males are called roosters.", ImageName = "PushPinIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Turkey", SubHeading = "Eaten at thanksgiving.", ImageName = "LightBulbIcon.png" });
tableItems.Add (tGroup);
//---- fish
tGroup = new BasicTableViewItemGroup() { Name = "Fish", Footer = "Fish live in water. Mostly." };
tGroup.Items.Add (new BasicTableViewItem() { Name = "Trout", SubHeading = "Rainbow is a popular kind.", ImageName = "TargetIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Salmon", SubHeading = "Good sushi.", ImageName = "PawIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Cod", SubHeading = "Flat fish.", ImageName = "LightBulbIcon.png" });
tableItems.Add (tGroup);
//---- mammals
tGroup = new BasicTableViewItemGroup() { Name = "Mammals", Footer = "Mammals nurse their young." };
tGroup.Items.Add (new BasicTableViewItem() { Name = "Deer", SubHeading = "Bambi.", ImageName = "PushPinIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Bats", SubHeading = "Fly at night.", ImageName = "TargetIcon.png" });
tableItems.Add (tGroup);
this._tableViewSource = new BasicTableViewSource(tableItems);
}
我们将挪用这个办法来创立数据源,完成在表格中显现数据的历程。
终极,在AppDelegate类中的FinishedLaunching办法中,在挪用window.MakeKeyAndVisible之前到场以下代码。
this.CreateTableItems ();
this.tblMain.Source = this._tableViewSource;
经由过程挪用这个办法,我们就创立了一个表格数据源,并把数据源赋值给表格。
终极的Main.cs应当像如许:
using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace Example_CustomUITableViewCells
{
public class Application
// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
BasicTableViewSource _tableViewSource;
// This method is invoked when the application has loaded its UI and its ready to run
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
this.CreateTableItems ();
this.tblMain.Source = this._tableViewSource;
// This method is required in iPhoneOS 3.0
public override void OnActivated (UIApplication application)
{
}
/// <summary>
/// Creates a set of table items.
/// </summary>
protected void CreateTableItems ()
{
List<BasicTableViewItemGroup> tableItems = new List<BasicTableViewItemGroup> ();
//---- declare vars
BasicTableViewItemGroup tGroup;
//---- birds
tGroup = new BasicTableViewItemGroup() { Name = "Birds", Footer = "Birds have wings, and sometimes use them." };
tGroup.Items.Add (new BasicTableViewItem() { Name = "Crow", SubHeading = "AKA, Raven.", ImageName = "PawIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Chicken", SubHeading = "Males are called roosters.", ImageName = "PushPinIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Turkey", SubHeading = "Eaten at thanksgiving.", ImageName = "LightBulbIcon.png" });
tableItems.Add (tGroup);
//---- fish
tGroup = new BasicTableViewItemGroup() { Name = "Fish", Footer = "Fish live in water. Mostly." };
tGroup.Items.Add (new BasicTableViewItem() { Name = "Trout", SubHeading = "Rainbow is a popular kind.", ImageName = "TargetIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Salmon", SubHeading = "Good sushi.", ImageName = "PawIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Cod", SubHeading = "Flat fish.", ImageName = "LightBulbIcon.png" });
tableItems.Add (tGroup);
//---- mammals
tGroup = new BasicTableViewItemGroup() { Name = "Mammals", Footer = "Mammals nurse their young." };
tGroup.Items.Add (new BasicTableViewItem() { Name = "Deer", SubHeading = "Bambi.", ImageName = "PushPinIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Bats", SubHeading = "Fly at night.", ImageName = "TargetIcon.png" });
tableItems.Add (tGroup);
this._tableViewSource = new BasicTableViewSource(tableItems);
}
这让我们的自界说单位格模板能够被重用,正如之前我们在代码中完成的那样。
我们已完成了InterfaceBuilder中事变了,那末保留文件,前往到MonoDevelop中。双击CustomTableCellView.xib.cs翻开这个类文件。
我们要对这个类举行一点编纂。起首,我们来增加一些属性到类内里:
public UITableViewCell Cell
{
get { return this.cellMain; }
}
public string Heading
{
get { return this.lblHeading.Text; }
set { this.lblHeading.Text = value; }
}
public string SubHeading
{
get { return this.lblSubHeading.Text; }
set { this.lblSubHeading.Text = value; }
}
public UIImage Image
{
get { return this.imgMain.Image; }
set { this.imgMain.Image = value; }
}
我们来看一下这些属性:
CellC这个属性让这个自界说单位格的挪用者能够间接会见单位格自己,以便在UITableViewSource的GetCell挪用中,我们能间接从一个属性复杂地前往,过一会我们会看到怎样弄。
Heading和SubHeadingC这个属性表露了能够间接会见表格单位格中UILabel控件的文本值。
ImageC这个属性间接表露表格单位格中的UIImage控件。
接上去,我们必要编纂个中一个机关器。文件在被MonoDevelop创立好后,文件中的最初一个机关器看起来以下:
public CustomTableViewCell () : base("CustomTableViewCell", null)
{
Initialize ();
}
这是一个十分复杂的机关器,假如你读过Mono文档关于基类机关申明的话,就会分明这里它会初始化这个类,并用我们传送出来的称号来加载Nib(编译好的.xib文件)文件。但是,文档中没有提到的是,基类机关器是异步的。假如你利用这类体例来挪用,那末Nib仿佛未被立即加载,在我们给自界说单位格设置诸如Heading属性的时分,我们会失掉厌恶的空援用毛病。
为了修改这个成绩,我们必需确保Nib文件同步地加载,即直到加载完成,办法是不会前往。
那末,就必要编纂机关器,以便看起来以下:
public CustomTableViewCell ()// : base("CustomTableViewCell", null)
{
//---- this next line forces the loading of the xib file to be synchronous
MonoTouch.Foundation.NSBundle.MainBundle.LoadNib ("CustomTableViewCell", this, null);
Initialize ();
}
在这里,我们起首要做到就是,把挪用基类机关器的代码正文失落。我们会手动地举行来挪用谁人代码,以是在这里不必再调一次。接上去,我们增加一个对LoadNib办法的挪用。它实践上和基类机关器所做的事变是一样的,除不会强迫举行异步处置。如今,我们确保了Nib和任何器材都能初始化,以便我们能会见它。
完全的类看上往以下所示:
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System;
public CustomTableViewCell ()// : base("CustomTableViewCell", null)
{
//---- this next line forces the loading of the xib file to be synchronous
MonoTouch.Foundation.NSBundle.MainBundle.LoadNib ("CustomTableViewCell", this, null);
Initialize ();
}
void Initialize ()
{
}
#endregion
public UITableViewCell Cell
{
get { return this.cellMain; }
}
public string Heading
{
get { return this.lblHeading.Text; }
set { this.lblHeading.Text = value; }
}
public string SubHeading
{
get { return this.lblSubHeading.Text; }
set { this.lblSubHeading.Text = value; }
}
public UIImage Image
{
get { return this.imgMain.Image; }
set { this.imgMain.Image = value; }
}
/// Combined DataSource and Delegate for our UITableView with custom cells
/// </summary>
public class CustomTableViewSource : UITableViewSource
{
//---- declare vars
protected List<BasicTableViewItemGroup> _tableItems;
protected string _customCellIdentifier = "MyCustomTableCellView";
protected Dictionary<int, CustomTableViewCell> _cellControllers =
new Dictionary<int, CustomTableViewCell>();
public CustomTableViewSource (List<BasicTableViewItemGroup> items)
{
this._tableItems = items;
}
/// <summary>
/// Called by the TableView to determine how many sections(groups) there are.
/// </summary>
public override int NumberOfSections (UITableView tableView)
{
return this._tableItems.Count;
}
/// <summary>
/// Called by the TableView to determine how many cells to create for that particular section.
/// </summary>
public override int RowsInSection (UITableView tableview, int section)
{
return this._tableItems[section].Items.Count;
}
/// <summary>
/// Called by the TableView to retrieve the header text for the particular section(group)
/// </summary>
public override string TitleForHeader (UITableView tableView, int section)
{
return this._tableItems[section].Name;
}
/// <summary>
/// Called by the TableView to retrieve the footer text for the particular section(group)
/// </summary>
public override string TitleForFooter (UITableView tableView, int section)
{
return this._tableItems[section].Footer;
}
/// <summary>
/// Called by the TableView to retreive the height of the row for the particular section and row
/// </summary>
public override float GetHeightForRow (UITableView tableView, MonoTouch.FoundationNSIndexPath indexPath)
{
return 109f;
}
/// <summary>
/// Called by the TableView to get the actual UITableViewCell to render for the particular section and row
/// </summary>
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.FoundationNSIndexPath indexPath)
{
//---- declare vars
//---- if there are no cells to reuse, create a new one
if (cell == null)
{
customCellController = new CustomTableViewCell ();
// retreive the cell from our custom cell controller
cell = customCellController.Cell;
// give the cell a unique ID, so we can match it up to the controller
cell.Tag = Environment.TickCount;
// store our controller with the unique ID we gave our cell
this._cellControllers.Add (cell.Tag, customCellController);
}
else
{
// retreive our controller via it"s unique ID
}
假如你扫瞄一遍这个代码,就看到它几近和BasicTableViewSource一样,只要少量改动。
要注重到第一件事,是声明部分:
//---- declare vars
protected List<BasicTableViewItemGroup> _tableItems;
protected string _customCellIdentifier = "MyCustomTableCellView";
protected Dictionary<int, CustomTableViewCell> _cellControllers =
new Dictionary<int, CustomTableViewCell>();
我们增加了一个名为_cellControllers新变量。我们将在前面看到怎样利用它,它会保留着自界说单位格的汇合。
下一个增添的器材是GetHeightForRow办法:
/// <summary>
/// Called by the TableView to retreive the height of the row for the particular section and row
/// </summary>
public override float GetHeightForRow (UITableView tableView, MonoTouch.FoundationNSIndexPath indexPath)
{
return 109f;
}
当我们创立自界说单位格把持器以后,我们让它比一般的单位格要高。在数据绑定的过程当中,CocoaTouch必要晓得要给这个单位格分派几空间。这就是要挪用GetHeightForRow办法的启事。假如我们不告诉新的巨细,那末体系会依照尺度尺寸往调剂结构,我们就会看到奇异的了局。
假如我们在InterfaceBuilder中翻开我们的单位格,并经由过程SizeInspector检察,会晓得单位格的高度上几。在我们的例子中,它是109像素,不外你的大概会有所分歧。
最初改动的一块中央是,GetCell办法:
/// <summary>
/// Called by the TableView to get the actual UITableViewCell to render for the particular section and row
/// </summary>
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.FoundationNSIndexPath indexPath)
{
//---- declare vars
//---- if there are no cells to reuse, create a new one
if (cell == null)
{
customCellController = new CustomTableViewCell ();
// retreive the cell from our custom cell controller
cell = customCellController.Cell;
// give the cell a unique ID, so we can match it up to the controller
cell.Tag = Environment.TickCount;
// store our controller with the unique ID we gave our cell
this._cellControllers.Add (cell.Tag, customCellController);
}
else
{
// retreive our controller via it"s unique ID
//---- return the custom cell
return cell;
}
这个办法入手下手十分相似于BasicTableViewSource类,我们实验经由过程DequeueReusableCell的挪用来从缓存池中重用的一个单位格。从这以后,就变得庞大了。假如我们不克不及在重用的时分失掉单位格,那末我们必需往创立一个新的。它就是由我们的CustomTableViewCell类所创立的,它实践上是一个包括着自界说单位格的把持器。
一旦我们创立了把持器,我们就把cell变量赋值把持器的Cell属性。
我们接着为单位格增加了一个独一标识符,以便我们在前面能把它和准确的CustomTableViewCell把持器联系关系在一同。我们利用Environment.TickCount,由于它供应了对照稳妥的独一性值。假如我们想,也能够利用Guid.NewGuid,不外挪用它略微有点高贵。
接上去,我们利用不异的tag标识,来创立存储在CustomTableViewCell的字典工具。
这也就是我们上面这行代码不言而喻的缘故原由:
else
{
// retreive our controller via it"s unique ID
customCellController = this._cellControllers[cell.Tag];
}
假如我们找到一个可重用的单位格,那末就必要经由过程把持器来设置相干属性。为了如许,必需利用之前我们利用过的标识符从Dictionary中提掏出来。
到这里,已触及了对这个类的年夜部分改动。接上去的几行,为了改动把持器类中的属性,举行了相对单位格自己较复杂的修正。
好了!我们将近完成了。翻开Main.cs文件,我们对AppDelegate类举行两个中央的改动,让其利用我们的CustomTableViewSource而非BasicTableViewSource。
起首,正文失落这行:
BasicTableViewSource _tableViewSource;
并紧接着后增加这行:
CustomTableViewSource _tableViewSource;
接着,在CreateTableItems办法中,正文失落这行:
this._tableViewSource = new BasicTableViewSource(tableItems);
并紧接着前面增加这行:
this._tableViewSource = new CustomTableViewSource(tableItems);
我们修正后的AppDelegate类看起来以下:
// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
//BasicTableViewSource _tableViewSource;
CustomTableViewSource _tableViewSource;
// This method is invoked when the application has loaded its UI and its ready to run
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
this.CreateTableItems ();
this.tblMain.Source = this._tableViewSource;
// This method is required in iPhoneOS 3.0
public override void OnActivated (UIApplication application)
{
}
/// <summary>
/// Creates a set of table items.
/// </summary>
protected void CreateTableItems ()
{
List<BasicTableViewItemGroup> tableItems = new List<BasicTableViewItemGroup> ();
//---- declare vars
BasicTableViewItemGroup tGroup;
//---- birds
tGroup = new BasicTableViewItemGroup() { Name = "Birds", Footer = "Birds have wings, and sometimes use them." };
tGroup.Items.Add (new BasicTableViewItem() { Name = "Crow", SubHeading = "AKA, Raven.", ImageName = "PawIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Chicken", SubHeading = "Males are called roosters.", ImageName = "PushPinIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Turkey", SubHeading = "Eaten at thanksgiving.", ImageName = "LightBulbIcon.png" });
tableItems.Add (tGroup);
//---- fish
tGroup = new BasicTableViewItemGroup() { Name = "Fish", Footer = "Fish live in water. Mostly." };
tGroup.Items.Add (new BasicTableViewItem() { Name = "Trout", SubHeading = "Rainbow is a popular kind.", ImageName = "TargetIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Salmon", SubHeading = "Good sushi.", ImageName = "PawIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Cod", SubHeading = "Flat fish.", ImageName = "LightBulbIcon.png" });
tableItems.Add (tGroup);
//---- mammals
tGroup = new BasicTableViewItemGroup() { Name = "Mammals", Footer = "Mammals nurse their young." };
tGroup.Items.Add (new BasicTableViewItem() { Name = "Deer", SubHeading = "Bambi.", ImageName = "PushPinIcon.png" });
tGroup.Items.Add (new BasicTableViewItem() { Name = "Bats", SubHeading = "Fly at night.", ImageName = "TargetIcon.png" });
tableItems.Add (tGroup);
//this._tableViewSource = new BasicTableViewSource(tableItems);
this._tableViewSource = new CustomTableViewSource(tableItems);
}
}
运转这个使用程序,就可以看到上面的效果: