New to Telerik UI for Xamarin? Download free 30-day trial

DataSource for Xamarin.iOS: Data Shaping Operations

TLKDataSource supports a full range of data shaping operations with APIs specific for your scenario.

The simplest way to shape your data is to use the block API. Just specify the block function responsible for the data operation:

// filter all values less or equal to 5
dataSource.Filter ((NSObject item) => {
    return ((NSNumber)item).NIntValue > 5;
});

// sort ascending
dataSource.Sort ((NSObject obj1, NSObject obj2) => {
    nint a = ((NSNumber)obj1).NIntValue;
    nint b = ((NSNumber)obj2).NIntValue;
    if (a<b) return NSComparisonResult.Descending; 
    else if (a>b) return NSComparisonResult.Ascending;
    return NSComparisonResult.Same;
});

// group odd/even values
dataSource.Group ((NSObject item) => {
    return NSObject.FromObject(((NSNumber)item).NIntValue % 2 == 0);
});

// multiply every value * 10
dataSource.Map ((NSObject item) => {
    return NSObject.FromObject(((NSNumber)item).NIntValue * 10);
});

// find the max value
NSObject maxValue = dataSource.Reduce (NSObject.FromObject(0), (NSObject item, NSObject value) => {
    if (((NSNumber)item).NIntValue > ((NSNumber)value).NIntValue) 
        return item;
    return value;
});

TLKDataSource supports also NSPredicate style queries. The following methods use queries and property names instead of block methods:

public class DataSourceDocsQueries : XamarinExampleViewController
{
    TLKDataSource dataSource;

    public DataSourceDocsQueries ()
    {
    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        NSMutableArray items = new NSMutableArray();
        items.Add (new DSItem () { Name = "John", Value = 50, Group = "A" });
        items.Add (new DSItem () { Name = "Abby", Value = 33, Group = "A" });
        items.Add (new DSItem () { Name = "Smith", Value = 42, Group = "B" });
        items.Add (new DSItem () { Name = "Peter", Value = 28, Group = "B" });
        items.Add (new DSItem () { Name = "Paula", Value = 25, Group = "B" });

        this.dataSource = new TLKDataSource();
        this.dataSource.ItemSource = items;
        this.dataSource.DisplayKey = "Name";

        this.dataSource.FilterWithQuery ("Value > 30");
        this.dataSource.SortWithKey ("Value", true);
        this.dataSource.GroupWithKey ("Group");


        UITableView tableView = new UITableView (this.View.Bounds);
        tableView.DataSource = this.dataSource;
        this.View.AddSubview (tableView);
    }
}

All the methods mentioned above execute immediately when called. They operate directly on the current Items view in TLKDataSource. TLKDataSource extends its API by supporting three collections with sorting, filtering and group descriptors.

The descriptors API supports both code blocks and queries with property names. This allows for specifying the data shaping operations before loading the data. In this scenario all descriptors are applied after the data is actually loaded in TLKDataSource. This data-loading operation can happen on setting the itemSource property. The following code demonstrates this API:

public class DataSourceDescriptorsAPI: XamarinExampleViewController
{
    TLKDataSource dataSource;

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        dataSource = new TLKDataSource ();

        dataSource.AddFilterDescriptor (new TKDataSourceFilterDescriptor ("NOT (Name like 'John')"));
        dataSource.AddSortDescriptor (new TKDataSourceSortDescriptor ("Name", true));
        dataSource.AddGroupDescriptor (new TKDataSourceGroupDescriptor ("Group"));

        var array = new NSMutableArray ();
        array.Add (new DSItem () { Name = "John", Value = 22.0f, Group = "one" });
        array.Add (new DSItem () { Name = "Peter", Value = 15.0f, Group = "one" });
        array.Add (new DSItem () { Name = "Abby", Value = 47.0f, Group = "one" });
        array.Add (new DSItem () { Name = "Robert", Value = 45.0f, Group = "two" });
        array.Add (new DSItem () { Name = "Alan", Value = 17.0f, Group = "two" });
        array.Add (new DSItem () { Name = "Saly", Value = 33.0f, Group = "two" });

        dataSource.DisplayKey = "Name";
        dataSource.ValueKey = "Value";
        dataSource.ItemSource = array;

        dataSource.FormatText ((NSObject item, TKDataSourceGroup group) => {
            DSItem dsItem = (DSItem)item;
            return new NSString(string.Format("{0} has {1} points", dsItem.Name, dsItem.Value));
        });

        var tableView = new UITableView (this.View.Bounds);
        tableView.DataSource = dataSource;
        this.View.AddSubview (tableView);
    }
}

You can modify descriptor collections by using the corresponding add and remove methods. You can reapply all descriptors when data has changed by calling the ReloadData method.

In this article