2014-10-03 10:00:00
Preview: DataGrid for Xamarin.Forms
Note
Update, 11 November 2014
Because the approach of this code prevents it from hosting Xamarin.Forms.View objects within cells, and because of current difficulties in getting a truly high-performance cross-platform drawing API on all three Xamarin.Forms platforms (insert unhappy face aimed at Windows Phone here), I have stopped work on this project for the time being.
However, I am currently working on another DataGrid implementation, implemented with a different approach. Sorry, nothing from my second attempt at a DataGrid has been released publicly yet. Watch my blog and Twitter for announcements.
What is it?
It's a Xamarin.Forms grid control for displaying data in rows and columns.
Where's the code?
Is this open source?
Yes. Apache License v2.
Why are you writing a grid?
Because I see an unmet need. Xamarin.Forms needs a good way to display row/column data. And it needs to be capable of handling lots (millions) of cells. And it needs to be really, really fast.
I'm one of the founders of Zumero. We're all about mobile apps for businesses dealing with data. Many of our customers are using Xamarin, and we want to be able to recommend Xamarin.Forms to them. A DataGrid is one of the pieces we need.
What are the features?
- Scrolling, both vertical and horizontal
- Either scroll range can be fixed, infinite, or wraparound.
- Optional headers, top, left, right, bottom.
- Ample flexibility in connecting to different data sources
- Column widths can be fixed width or variable. Same for row heights.
Is this ready for use?
No, this code is still pretty rough.
Is this ready to play with and complain about?
Yes, hence its presence on GitHub. :-)
Open dg.sln in Xamarin Studio and it should build. There's a demo app (Android and iOS) you can use to try it out. The WP8 code isn't there yet, but it'll be moving in soon.
Is there a NuGet package?
Not yet.
Is the API frozen yet?
No. In fact, I'm still considering some API changes that could be described as major.
What platforms does it support?
Android and iOS are currently in decent shape. Windows Phone is in progress. (The header row was bashful and refused to cooperate for the WP8 screenshot.)
What will the API be like?
I don't know yet. In fact, I'm tempted to quibble when you say "the API", because you're speaking of it in the singular, and I think I will end up with more than one. :-)
Earlier, I described this thing as "a grid control", but it would be more accurate right now to describe it as a framework for building grid controls.
I have implemented some sample grids, mostly just to demonstrate the framework's capabilities and to experiment with what kinds of user-facing APIs would be most friendly. Examples include:
- A grid that gets its data from an IList
, where the properties of objects of class T become columns. - A data connector that gets its data from ReactiveList (uses ReactiveUI).
- A grid that gets its data from a sqlite3_stmt handle (uses my SQLitePCL.raw package).
- A grid that just draws shapes.
- A grid that draws nothing but a cell border, but the farther you scroll, the bigger the cells get.
- A 2x2 grid that scrolls forever and just repeats its four cells over and over.
How is this different from the layouts built into Xamarin.Forms?
This control is not a "Layout", in the Xamarin.Forms sense. It is not a subclass of Xamarin.Forms.Layout. You can't add child views to it.
If you need something to help arrange the visual elements of your UI on the screen, DataGrid is not what you want. Just use one of the Layouts. That's what they're for.
But maybe you need to display a lot of data. Maybe you have 200,000 rows. Maybe you don't know how many rows you have and you won't know until you read the last one. Maybe you have lots of columns too, so you need the ability to scroll in both directions. Maybe you need one or more header rows at the top which sync-scroll horizontally but are frozen vertically. And so on.
Those kind of use cases are what DataGrid is aimed for.
What drawing API are you using?
Mostly I'm working with a hacked-up copy of Frank Krueger's CrossGraphics library, modified in a variety of ways.
The biggest piece of the code (in DataGrid.Core) actually doesn't care about the graphics API. That assembly contains generic classes which accept <TGraphics> as a type parameter. (As a proof of concept demo, I've got an iOS implementation built on CGContext which doesn't actually depend on Xamarin.Forms at all.)
So I can't add ANY child views to your DataGrid control?
Currently, no. I would like to add this capability in the future.
(At the moment, I'm pretty sure it is impossible to build a layout control for Xamarin.Forms unless you're a Xamarin employee. There seem to be a few important things that are not public.)
How fast is it?
Very. On my Nexus 7, a debug build of DataGrid can easily scroll a full screen of text cells at 60 frames/second. Performance on iOS is similar.
How much code is cross-platform?
Not counting the demo app or my copy of CrossGraphics, the following table shows lines of code in each combination of dependencies:
Portable | iOS-specific | Android-specific | |
<TGraphics> | 2,741 | 141 | 174 |
Xamarin.Forms | 633 | 92 | 81 |
Xamarin.Forms is [going to be] a wonderful foundation for cross-platform mobile apps.
Can I use this from Objective-C or Java?
No. It's all C#.
Why are you naming_things_with_underscores?
Sorry about that. It's a habit from my Unix days that I keep slipping back into. I'll clean up my mess soon.
What's up with IChanged? Why not IObservable<T>?
Er, yeah, remember above when I said I'm still considering some major changes? That's one them.
Does this in any way depend on your Zumero for SQL Server product?
No, DataGrid is a standalone open source library.
But it's rather likely that our commercial products will in the future depend on DataGrid.