As you may have see in our previous blog post, http://blog.androidjetpack.com/post/Android-DataGrid-Xamarin-Support-Added-Java-Binding-Project-Issues.aspx. we have been working on a Xamarin port of our Android JetPack DataGrid component. With 2.1 release, we have accomplished this!

API Changes

From an API perspective, there were a few changes, primarily to match the "Xamarin way" of doing things. Here are the API changes. They are very minimal, but if you are using sample code from previous versions, you may need to make these changes:

1) Removed com.flexicious.controls.core.IExtendedView#getEnabled() (Change this to .isEnabled())

2) Removed com.flexicious.controls.core.IExtendedView#setEnabled(java.lang.Boolean)

3) Removed com.flexicious.controls.interfaces.filters.IFilterControl.validateNow()

4) Minor interface changes to ISelectFilterControl, ITriStateCheckBoxFilterControl, IDataGridFilterColumn

5) Removed the toaster package, since we use built in Android Toast

6) Added setOnAllEventListener & getOnAllEventListener to FlexDataGrid. This allows you to do grid.AllEvent += delegate (Xamarin way, in case you dont want to use the regular event function call back mechanism). 

7) If you get errors in compiling StyleManager 

Please replace 

 grid.paddingBottom = 2;

              grid.paddingLeft = 2;

              grid.paddingRight = 2;

 

              grid.paddingTop = 2;

With: 

grid.cellPaddingBottom = 2;

              grid.cellPaddingLeft = 2;

              grid.cellPaddingRight = 2;

              grid.cellPaddingTop = 2;

 

8) You may also need to change .getEnabled to .isEnabled. 

These properties were renamed because they clashed with some Xamarin naming conventions


Most of these changes should not mean much to you, unless you are programming deep inside the exposed API.

Getting Started With Xamarin & Android JetPack

1) The first thing to do, is to add the usual resources to the drawable, raw, layout, folders, and making changes to AndroidManfiest.xml as demonstrated in the getting started guide. (http://www.androidjetpack.com/newdocs/html/AndroidJetPackAndroidDataGrid.html)

2) Second, is as usual, to add the reference to the XamarinStudioBindings.dll file that is included in the Sample Download

3) Third, in your Main.axml file, just add the FlexDataGrid component, similar to how it would be added in Android Studio or Eclipse. (http://www.androidjetpack.com/newdocs/html/AndroidJetPackAndroidDataGrid.html?PlacingtheAndroidDataGridinyourv.html) - You can see this in the file you downladed. 

4) In your MainActivity, you can get a handle to the grid, build it using a XML configuration, provide a Data Provider, and wire up event handlers. 

Lets take a quick look at the important pieces of the MainActivity:

using System;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Com.Flexicious.Nestedtreedatagrid;
using Com.Flexicious.Nestedtreedatagrid.Valueobjects;
using System.Collections.Generic;
using Java.IO;
using Java.Lang;
using Com.Flexicious.Nestedtreedatagrid.Events;
using Com.Flexicious.Nestedtreedatagrid.Interfaces;
using Com.Flexicious.Controls.Core;
using Android.Graphics;

namespace AndroidApp
{
    [Activity (Label = "AndroidApp", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        int count = 1;
        FlexDataGrid flexDataGrid;

        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);

            // Set our view from the "main" layout resource
            SetContentView (Resource.Layout.Main);

            // Get our button from the layout resource,
            // and attach an event to it
            Button button = FindViewById<Button> (Resource.Id.myButton);
            
            button.Click += delegate {
                button.Text = string.Format ("{0} clicks!", count++);
            };

            //Here, we get a reference to the Android JetPack DataGrid component
            flexDataGrid = FindViewById<FlexDataGrid> (Resource.Id.flexDataGrid1);

            //Here, we setup a dataprovider - the objects in the DataProvider MUST inherit from Java.Lang.Object, OR expose 
            //themselves to the ACW using the EXPORT attribute
            IList<object> list = new List<object> ();
            for (int i = 0; i < 1000; i++) {
                list.Add(new NameValue("Name " + i, "Value " + i));
            }
            //HERE, we build the grid using the XML config in grid_config.xml raw resource
            BuildGrid(flexDataGrid, Resource.Raw.grid_config);
            //Now, we set the data provider on the grid.
            flexDataGrid.DataProvider=(list);

            //Finally, if you are using ItemRenderers, they cannot be set in XML, you need to use API to set them like below. 
            //Also, please ensure that the setData and getData methods are exported via the Java.Interop.Export attribute. 
            //flexDataGrid.GetColumnByDataField ("data").ItemRenderer = new ClassFactory (new TextInputRenderer(this).Class);
        
        }
        //This is an example of a CALLBACK function. The key is to ensure 1) Both the arguments and the return value inherit from Java.Lang.Object
        //And 2) That you add the Java.Interop.Export Attribute as shown below.
        [Java.Interop.Export("getCellBackground")]
        public Java.Lang.Object getCellBackground(IFlexDataGridCell cell) {

            if (!cell.RowInfo.IsDataRow.BooleanValue()) {
                return null;
            }
            if (cell.Column.DataField==("data")) {
                return new Java.Lang.Integer (Color.Red);// null;//Color.Red;
            } else if (cell.Text==("Name 1")) {
                return new Java.Lang.Integer (Color.Blue);// null;//Color.Red;
            }
            //this makes the grid use whatever color it would have by default.
            return null;
        }

        //This is an example of a Event Handler function. The key is to ensure 1) Both the arguments and the return value inherit from Java.Lang.Object
        //And 2) That you add the Java.Interop.Export Attribute as shown below.
        [Java.Interop.Export("onItemClick")]
        public  void onItemClick(FlexDataGridEvent e){
            Toast.MakeText(this"You Clicked on : "+((NameValue) e.Cell.RowInfo.Data).Label, ToastLength.Short).Show();
        }
        [Java.Interop.Export("onChange")]
        public  void onChange(FlexDataGridEvent e){
            Toast.MakeText(this"Grid Selection Changed : Items selected : " + e.Grid.SelectedObjects.Count, ToastLength.Short).Show();
        }

        /**
        * Takes a grid, and an XML configuration, loads the XML configuration into the Grid.
        * @param grid
        * @param resource
        */
        public void BuildGrid(FlexDataGrid grid, int resource) {
            grid.Delegate = (this);
            BufferedReader reader = new BufferedReader(new InputStreamReader(this
                .Resources.OpenRawResource(resource)));
            StringBuilder builder = new StringBuilder();
            string aux = "";
            try {
                while ((aux = reader.ReadLine()) != null) {
                    builder.Append(aux);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            string text = builder.ToString();
            grid.BuildFromXml(text);
        }


    
    }
}