Thursday, July 21, 2011

iAdd sample for Monotouch app.

This sample shows how to display a banner Add on a montouch app.
I'm using a simple example to show the use of AdBannerView control.
Create a sample Iphone Navigation-based project from Monodevelop.
In Main.cs/AppDelegate class/FinishedLaunching() method add the following code.

public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
        ADBannerView banner = new ADBannerView(); 
        banner.CurrentContentSizeIdentifier = "ADBannerContentSizePortrait";
        banner.AdLoaded += delegate(object sender, EventArgs e) {
        banner.Hidden = false;
        };
        banner.FailedToReceiveAd += delegate(object sender, AdErrorEventArgs e) {
        banner.Hidden = true;
        };
        banner.Frame = new System.Drawing.RectangleF(0, 30, 320, 50);
        navigationController.Add(banner);
        window.AddSubview (navigationController.View);
        window.MakeKeyAndVisible ();
        return true;
}

The banner must be set to "ADBannerContentSizePortrait" or "ADBannerContentSizeLandscape" using CurrentContentSizeIdentifier property. In this example I'm only targeting portrait layout.
There are two delegates associated with the banner.
FailedToReceiveAd - This is when there is no connection between the app and the iAdd server, the banner is hidden in this case.
AdLoaded - When the iAdd server sends the Add content to display, this is then showed on the Add.




Tuesday, February 1, 2011

Hide Right Bar(EDIT) Button of MoreNavigationController of a UITabBarController using Monotouch

To remove the Edit button from the "More" Navigation controller in a UITabBarController as shown.



First assign a delegate class to the instance of the MoreNavigatioController in the AppDelegate class

tabBarController.MoreNavigationController.Delegate = new MoreNavigationControllerDelegate();


public partial class AppDelegate : UIApplicationDelegate
{
  TabBarController tabBarController;
  // This method is invoked when the application has loaded its UI and its ready to run
  public override bool FinishedLaunching (UIApplication app, NSDictionary options)
  {
     // Create the tabs
      tabBarController = new TabBarController ();
      tabBarController.MoreNavigationController.Delegate = new MoreNavigationControllerDelegate();
   
     // Create the main window and add the navigation controller as a subview
      window = new UIWindow (UIScreen.MainScreen.Bounds);
      window.AddSubview(tabBarController.View);
      window.MakeKeyAndVisible ();
      return true;
  }

  // This method is required in iPhoneOS 3.0
  public override void OnActivated (UIApplication application)
  {
  }
}
 


  • Add a new class "MoreNavigationControllerDelegate" to the project.
  • This class should implement "UINavigationControllerDelegate".
  • Add an override method  "WillShowViewController" to this class - This method is called whenever its time to load the MoreNavigation view controller.
  • Set the RightBarButtonItem to null in this method.
The following code in "WillShowViewController" method will hide "Edit" button in the "More" controller of UITabBarController.

public class MoreNavigationControllerDelegate : UINavigationControllerDelegate
 {
  public MoreNavigationControllerDelegate () : base()
  {
  }
  
  public override void WillShowViewController (UINavigationController navigationController, UIViewController viewController, bool animated)
  {
   if(navigationController.NavigationBar.TopItem.Title == "More")
    navigationController.NavigationBar.TopItem.RightBarButtonItem = null;
  }
 }



Note- I have the condition if(navigationController.NavigationBar.TopItem.Title == "More"), since I still want to show the right bar button when I select the "Motivation", "Tips" and "Glossary" view controller as shown below.


Thursday, December 9, 2010

Monotouch - Set custom RGB colors.

If you have a custom color with its corresponding RGB values, you can create a new UIColor variable by using the following code.

   float red = 0.0f;           // Defines the red component of the color object. This range is from 0.0f to 255.0f
   float green = 255.0f;       // Defines the green component of the color object. This range is from 0.0f to 255.0f
   float blue = 0.0f;          // Defines the blue component of the color object. This range is from 0.0f to 255.0f
   float alpha = 1.0f;         // Defines the opacity value of the color object. This range is from 0.0f to 1.0f

   UIColor newColor = new UIColor(red/255.0f, green/255.0f, blue/255.0f, alpha);
 

Following website is helpful if you are looking for RGB values for a color.
http://www.colorschemer.com/online.html

Wednesday, November 10, 2010

Delete Table Cells from UITableView in Monotouch

I came across a blog entry with a video to show how this is done.
Here is the link

Monday, October 4, 2010

Windows 7 phone developers launch

October 12th is Windows 7 phone developers launch.

Click on the banner to learn more.


Wednesday, September 1, 2010

Pass Custom UDT types to Oracle Stored Procedure using ODP.NET

Introduction: I came across a situation where I have a list of .Net custom objects and I want to pass this list to an Oracle procedure to process them. I did not want to loop through and update each record as I wanted to reduce the number of network round trips. And I found the following way to accomplish this. I had to create a User Defined Type (UDT) / Custom Type in Oracle that represents my .Net Object and another UDT as a table of these objects. Then I used ODP.Net to map between my .Net Custom Objects to Oracle UDT types


Prerequisites: ODP.NET 11g, Visual Studio 2005 / 2008 / 2010

Following are the UDT declarations in Oracle
----------------------------------------------------------------
create or replace type "COMPANYINFO" AS OBJECT
(
    CompanyId     varchar2(15),
    CompanyName   varchar2(50),
    Address1      varchar2(100),
    Address2      varchar2(100),
    City          varchar2(20),
    State         varchar2(20),
    Zip           varchar2(10),
    Country       varchar2(20)
);
   
create or replace type "COMPANYINFOLIST" is table of COMPANYINFO;
----------------------------------------------------------------

Procedure is defined as
----------------------------------------------------------------
procedure GetCompanyInfoArray(companyInfoList in COMPANYINFOLIST, resultCursor out sys_refcursor) is
 results stringSet;
 compName varchar2(100);
 begin
      if companyInfoList.count > 0 then
         results := stringSet();
          for i in companyInfoList.first .. companyInfoList.last
          loop 
           -- dbms_output.put_line(companyInfoList(i).companyId);              
              results.extend(1);
              results(results.count) := companyInfoList(i).companyName;  
          end loop;                   
      end if;  
      
      open resultCursor for
            select column_value as compName from table(cast (results as stringSet));
 end;
----------------------------------------------------------------
Following type is used by the procedure to add company names back to the return cursor
----------------------------------------------------------------
CREATE OR REPLACE TYPE "STRINGSET" is table of varchar(32000);
----------------------------------------------------------------

Open Visual Studio and create a new sample project "OracleUDTSample"
Add reference to Oracle.DataAccess.dll to the project. This dll is located in oracle home directory as shown.




Add following classes to the project
  • CompanyInfoThis class to represent Oracle type "COMPANYINFO" This class needs to inherit following interfaces - INullable, IOracleCustomType. Implement the INullable method IsNull  and IOracleCustomType methods FromCustomObject, ToCustomObject.
  • CompanyInfoFactory - This class is required by ODP.NET to create custom objects that represent oracle custom objects and collections. This should implement IOracleCustomTypeFactory.
  • CompanyInfoList -This class to represent Oracle type "COMPANYINFOLIST". This type is used to pass a list of COMPANYINFO objects. This class also implements INullable, IOracleCustomType interfaces. This class has an array of CompanyInfo property to capture the CompanyInfo object list.
  • CompanyInfoListFactory This class is required by ODP.NET to create custom objects that represent oracle custom objects and collections. This should also implement OracleCustomTypeFactory.




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Oracle.DataAccess.Types;

namespace OracleUDTSample
{
    /* CompanyInfo Class
    **   An instance of a CompanyInfo class represents an CompanyInfo object
    **   A custom type must implement INullable and IOracleCustomType interfaces
    */
    public class CompanyInfo : INullable, IOracleCustomType
    {
        private bool objectIsNull;

        [OracleObjectMappingAttribute("COMPANYID")]
        public string CompanyId { get; set; }
        
        [OracleObjectMappingAttribute("COMPANYNAME")]
        public string CompanyName { get; set; }

        [OracleObjectMappingAttribute("ADDRESS1")]
        public string Address1 { get; set; }

        [OracleObjectMappingAttribute("ADDRESS2")]
        public string Address2 { get; set; }

        [OracleObjectMappingAttribute("CITY")]
        public string City { get; set; }

        [OracleObjectMappingAttribute("STATE")]
        public string State { get; set; }

        [OracleObjectMappingAttribute("ZIP")]
        public string Zip { get; set; }

        [OracleObjectMappingAttribute("COUNTRY")]
        public string Country { get; set; }

        public static CompanyInfo Null
        {
            get
            {
                CompanyInfo company = new CompanyInfo();
                company.objectIsNull = true;
                return company;
            }
        }

        #region INullable Members

        public bool IsNull
        {
            get { return objectIsNull; }
        }

        #endregion

        #region IOracleCustomType Members

        public void FromCustomObject(Oracle.DataAccess.Client.OracleConnection con, IntPtr pUdt)
        {
            // Convert from the Custom Type to Oracle Object
            if (!string.IsNullOrEmpty(CompanyId))
            {
                OracleUdt.SetValue(con, pUdt, "COMPANYID", CompanyId);
            }
            if (!string.IsNullOrEmpty(CompanyName))
            {
                OracleUdt.SetValue(con, pUdt, "COMPANYNAME", CompanyName);
            }
            if (!string.IsNullOrEmpty(Address1))
            {
                OracleUdt.SetValue(con, pUdt, "ADDRESS1", Address1);
            }
            if (!string.IsNullOrEmpty(Address2))
            {
                OracleUdt.SetValue(con, pUdt, "ADDRESS2", Address2);
            }
            if (!string.IsNullOrEmpty(City))
            {
                OracleUdt.SetValue(con, pUdt, "CITY", City);
            }
            if (!string.IsNullOrEmpty(State))
            {
                OracleUdt.SetValue(con, pUdt, "STATE", State);
            }
            if (!string.IsNullOrEmpty(Zip))
            {
                OracleUdt.SetValue(con, pUdt, "ZIP", Zip);
            }
            if (!string.IsNullOrEmpty(Country))
            {
                OracleUdt.SetValue(con, pUdt, "COUNTRY", Country);
            }

        }

        public void ToCustomObject(Oracle.DataAccess.Client.OracleConnection con, IntPtr pUdt)
        {
            CompanyId = (string)OracleUdt.GetValue(con, pUdt, "COMPANYID");
            CompanyName = (string)OracleUdt.GetValue(con, pUdt, "COMPANYNAME");
            Address1 = (string)OracleUdt.GetValue(con, pUdt, "ADDRESS1");
            Address2 = (string)OracleUdt.GetValue(con, pUdt, "ADDRESS2");
            City = (string)OracleUdt.GetValue(con, pUdt, "CITY");
            State = (string)OracleUdt.GetValue(con, pUdt, "STATE");
            Zip = (string)OracleUdt.GetValue(con, pUdt, "ZIP");
            Country = (string)OracleUdt.GetValue(con, pUdt, "COUNTRY");
        }

        #endregion

    }

    [OracleCustomTypeMappingAttribute("DATABASE_SCHEMA_NAME.COMPANYINFO")]
    public class CompanyInfoFactory : IOracleCustomTypeFactory
    {
        #region IOracleCustomTypeFactory Members

        public IOracleCustomType CreateObject()
        {
            return new CompanyInfo();
        }

        #endregion
    }


   
   /* CompanyInfoList Class
   **   An instance of a CompanyInfoList class represents an CompanyInfoList object
   **   A custom type must implement INullable and IOracleCustomType interfaces
   */
    public class CompanyInfoList : INullable, IOracleCustomType
    {
        [OracleArrayMapping()]
        public CompanyInfo[] CompanyInfoArray;

        private bool objectIsNull;

        #region INullable Members

        public bool IsNull
        {
            get { return objectIsNull; }
        }

        public static CompanyInfoList Null
        {
            get
            {
                CompanyInfoList obj = new CompanyInfoList();
                obj.objectIsNull = true;
                return obj;
            }
        }

        #endregion

        #region IOracleCustomType Members

        public void FromCustomObject(Oracle.DataAccess.Client.OracleConnection con, IntPtr pUdt)
        {
            OracleUdt.SetValue(con, pUdt, 0, CompanyInfoArray);
        }

        public void ToCustomObject(Oracle.DataAccess.Client.OracleConnection con, IntPtr pUdt)
        {
            CompanyInfoArray = (CompanyInfo[])OracleUdt.GetValue(con, pUdt, 0);
        }

        #endregion
    }

    [OracleCustomTypeMapping("DATABASE_SCHEMA_NAME.COMPANYINFOLIST")]
    public class CompanyInfoListFactory :  IOracleCustomTypeFactory, IOracleArrayTypeFactory
    {
        #region IOracleCustomTypeFactory Members
        public IOracleCustomType CreateObject()
        {
            return new CompanyInfoList();
        }

        #endregion

        #region IOracleArrayTypeFactory Members
        public Array CreateArray(int numElems)
        {
            return new CompanyInfo[numElems];
        }

        public Array CreateStatusArray(int numElems)
        {
            return null;
        }

        #endregion
    }
}

Add new class DBAccess to add the database handling code. In this class we add CreateCustomTypeArrayInputParameter method to create our new OracleParameter to pass User Defined Type to Oracle. Make sure to add the following using statements -
using Oracle.DataAccess.Client
using Oracle.DataAccess.Types

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;

namespace OracleUDTSample
{
    public class DBAccess : IDisposable
    {
        OracleConnection connection;
        public OracleCommand CreateCommand(string sql, CommandType type, params OracleParameter[] parameters)
        {
            connection = new OracleConnection("Data Source=database_name;User ID=userid;Password=pwd;Pooling=true;Connection Lifetime=600;Max Pool Size=10;Min Pool Size=0");
            connection.Open();
            OracleCommand command = new OracleCommand(sql, connection);
            command.CommandType = type;
            if (parameters != null && parameters.Length > 0)
            {
                OracleParameterCollection cmdParams = command.Parameters;
                for (int i = 0; i < parameters.Length; i++) { cmdParams.Add(parameters[i]); }
            }
            return command;
        }

        public OracleDataReader GetDataReader(string storedProcedure, params OracleParameter[] parameters)
        {
            return CreateCommand(storedProcedure, CommandType.StoredProcedure, parameters).ExecuteReader();
        }

        public static OracleParameter CreateCursorParameter(string name)
        {
            OracleParameter prm = new OracleParameter(name, OracleDbType.RefCursor);
            prm.Direction = ParameterDirection.Output;
            return prm;
        }

        /*
         * Create this parameter when you want to pass Oracle User-Defined Type (Custom Type) which is table of Oracle User-Defined Types.                  
         * This way you can pass mutiple records at once.
         * 
         * Parameters:
         * name - Name of the UDT Parameter name in the Stored Procedure.
         * oracleUDTName - Name of the Oracle User Defined Type with Schema Name. (Make sure this is all caps. For ex: DESTINY.COMPANYINFOLIST)
         * 
         * */
        public static OracleParameter CreateCustomTypeArrayInputParameter<t>(string name, string oracleUDTName, T value) where T : IOracleCustomType, INullable
        {
            OracleParameter parameter = new OracleParameter();
            parameter.ParameterName = name;
            parameter.OracleDbType = OracleDbType.Array;
            parameter.Direction = ParameterDirection.Input;
            parameter.UdtTypeName = oracleUDTName;
            parameter.Value = value;
            return parameter;
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (connection != null)
                connection = null;
        }

        #endregion
    }
}

Create a new CompanyInfoInterface class which defines a method GetCompanyInfo. This method is creates the procedure parameters and calls the procedure using the DBAccess class.
public class CompanyInfoInterface
{
   #region Constants
   private const string procName = "Package_Name.GetCompanyInfoArray";
   #endregion

   public static List<string> GetCompanyinfo(List<companyinfo> companyList)
   {
     List<string> companyNames = new List<string>();
     CompanyInfoList companyInfoList = new CompanyInfoList();
     companyInfoList.CompanyInfoArray = companyList.ToArray();

     using (DBAccess context = new DBAccess())
     {
         try
         {
            OracleParameter[] parameters = new OracleParameter[2];
            parameters[0] = DBAccess.CreateCustomTypeArrayInputParameter<companyinfolist>("companyInfoList", "DATABASE_SCHEMA.COMPANYINFOLIST", companyInfoList);
            parameters[1] = DBAccess.CreateCursorParameter("resultCursor");
            using (OracleDataReader dr = context.GetDataReader(procName, parameters))
            {
               while (dr.Read())
               {
                 companyNames.Add(dr.IsDBNull(0) ? string.Empty : dr.GetString(0));
               }
           }
         }
         catch
         {
           throw;
         }
         return companyNames;
     }
   }
 }
Finally the Test class
public class Test
{
    static void Main(string[] args)
    {
       List<CompanyInfo> companyList = new List<CompanyInfo>();
       CompanyInfo company1 = new CompanyInfo();
       company1.CompanyId = "AAA";
       company1.CompanyName = "Sample Company 1";
       company1.Address1 = "123 West Washington";
       company1.Address2 = "Suite 200";
       company1.City = "Chicago";
       company1.State = "IL";
       company1.Zip = "60606";
       company1.Country = "USA";
       companyList.Add(company1);

       company1 = new CompanyInfo();
       company1.CompanyId = "BBB";
       company1.CompanyName = "Sample Company 2";
       company1.Address1 = "990 West Jackson";
       company1.Address2 = "Suite 1000";
       company1.City = "Chicago";
       company1.State = "IL";
       company1.Zip = "60606";
       company1.Country = "USA";

       companyList.Add(company1);
       List<string> result = CompanyInfoInterface.GetCompanyinfo(companyList);

       string val = result.Where(c => c == "Sample Company 2").SingleOrDefault<string>();
       Console.WriteLine(val);
       Console.ReadLine();
   }
}

Sunday, July 25, 2010

Disable Edit Button on "More" tab of UITabBarController using Monotouch

Today I will show you how to disable the Edit button on "More" tab of UITabBarController.
Following screen shot displays a tab bar controller displaying "More" tab with 2 items and an edit button on top right side of navigation bar.

Clicking the button brings up a configure view where all the tabs are displayed and can be moved around as shown below.

Adding the following code in ViewDidLoad() method  of your UITabBarController class removes the items from the "Configure" view. 
/* */
this.CustomizableViewControllers = null;
/* */

Adding the following code in ViewDidLoad() method  of your UITabBarController class disables the "Edit" button.
/* */
this.MoreNavigationController.NavigationBar.TopItem.RightBarButtonItem.Enabled = false;
/* */