Friday, September 11, 2015

Hidden Features of C#

Hidden Features of C#

 


1. ObsoleteAttribute

ObsoleteAttribute applies to all program elements except assemblies, modules, parameters, and return values. Marking an element as obsolete informs users that the element will be removed in future versions of the product.
Message property contains a string that will be displayed when the attribute assignee is used. It is recommended a workaround to be provided in this description.
IsError– If set to true the compiler will indicate an error if the attribute target is used in the code.
public static class ObsoleteExample
{
    // Mark OrderDetailTotal As Obsolete.
    [ObsoleteAttribute("This property (DepricatedOrderDetailTotal) is obsolete. Use InvoiceTotal instead.", false)]
    public static decimal OrderDetailTotal
    {
        get
        {
            return 12m;
        }
    }

    public static decimal InvoiceTotal
    {
        get
        {
            return 25m;
        }
    }

    // Mark CalculateOrderDetailTotal As Obsolete.
    [ObsoleteAttribute("This method is obsolete. Call CalculateInvoiceTotal instead.", true)]
    public static decimal CalculateOrderDetailTotal()
    {
        return 0m;
    }

    public static decimal CalculateInvoiceTotal()
    {
        return 1m;
    }
}
If we use the above class in our code, an error, and a warning are going to be displayed.
Console.WriteLine(ObsoleteExample.OrderDetailTotal);
Console.WriteLine();
Console.WriteLine(ObsoleteExample.CalculateOrderDetailTotal());
Official documentation– https://msdn.microsoft.com/en-us/library/system.obsoleteattribute.aspx

2. Setting a default value for C# Auto-implemented properties via DefaultValueAttribute

DefaultValueAttribute specifies the default value for a property. You can create a DefaultValueAttribute with any value. A member’s default value is typically its initial value.
The attribute won’t cause a member to be automatically initialized with the specified value. Hence, you must set the initial value in your code.
public class DefaultValueAttributeTest
{
    public DefaultValueAttributeTest()
    {
        // Use the DefaultValue propety of each property to actually set it, via reflection.
        foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(this))
        {
            DefaultValueAttribute attr = (DefaultValueAttribute)prop.Attributes[typeof(DefaultValueAttribute)];
            if (attr != null)
            {
                prop.SetValue(this, attr.Value);
            }
        }
    }

    [DefaultValue(25)]
    public int Age { get; set; }

    [DefaultValue("Anton")]
    public string FirstName { get; set; }

    [DefaultValue("Angelov")]
    public string LastName { get; set; }

    public override string ToString()
    {
        return string.Format("{0} {1} is {2}.", this.FirstName, this.LastName, this.Age);
    }
}
The auto-implemented properties are initialized in the constructor of the class via reflection. The code iterates through all properties of the class and set them their default value if the DefaultValueAttribute is present.
Official documentationhttps://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx

3. DebuggerBrowsableAttribute

Determines if and how a member is displayed in the debugger variable windows.
public static class DebuggerBrowsableTest
{
    private static string squirrelFirstNameName;
    private static string squirrelLastNameName;

    // The following DebuggerBrowsableAttribute prevents the property following it 
    // from appearing in the debug window for the class.
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public static string SquirrelFirstNameName 
    {
        get
        {
            return squirrelFirstNameName;
        }
        set
        {
            squirrelFirstNameName = value;
        }
    }

    [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
    public static string SquirrelLastNameName
    {
        get
        {
            return squirrelLastNameName;
        }
        set
        {
            squirrelLastNameName = value;
        }
    }
}
If you use the sample class in your code and try to step through it via the debugger (F11), you will notice that the code is just executing.
DebuggerBrowsableTest.SquirrelFirstNameName = "Hammy";
DebuggerBrowsableTest.SquirrelLastNameName = "Ammy";
Official documentationhttps://msdn.microsoft.com/en-us/library/system.diagnostics.debuggerbrowsableattribute.aspx

4. ?? Operator

One of my favorite “hidden features of C#” is the ?? operator. I’m using it heavily in my code.
The ?? operator returns the left-hand operand if it is not null, or else it returns the right operand. A nullable type can contain a value, or it can be undefined. The ?? operator defines the default value to be returned when a nullable type is assigned to a non-nullable type.
int? x = null;
int y = x ?? -1;
Console.WriteLine("y now equals -1 because x was null => {0}", y);
int i = DefaultValueOperatorTest.GetNullableInt() ?? default(int);
Console.WriteLine("i equals now 0 because GetNullableInt() returned null => {0}", i);
string s = DefaultValueOperatorTest.GetStringValue();
Console.WriteLine("Returns 'Unspecified' because s is null => {0}", s ?? "Unspecified");
Official documentationhttps://msdn.microsoft.com/en-us/library/ms173224(v=vs.80).aspx

5. Curry and Partial methods

Curry– In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument.
In order to be implemented via C#, the power of the extension methods is used.
public static class CurryMethodExtensions
{
    public static Func<A, Func<B, Func<C, R>>> Curry<A, B, C, R>(this Func<A, B, C, R> f)
    {
        return a => b => c => f(a, b, c);
    }
}
The curry extension method usage is a little bit overwhelming at first.
Func<int, int, int, int> addNumbers = (x, y, z) => x + y + z;
var f1 = addNumbers.Curry();
Func<int, Func<int, int>> f2 = f1(3);
Func<int, int> f3 = f2(4);
Console.WriteLine(f3(5));
The types returned by the different methods can be exchanged with the var keyword.
Official documentationhttps://en.wikipedia.org/wiki/Currying#/Contrast_with_partial_function_application
Partial – in computer science, partial application (or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity.
public static class CurryMethodExtensions
{
    public static Func<C, R> Partial<A, B, C, R>(this Func<A, B, C, R> f, A a, B b)
    {
        return c => f(a, b, c);
    }
}
The partial extension method usage is more straightforward than the curry one.
Func<int, int, int, int> sumNumbers = (x, y, z) => x + y + z;
Func<int, int> f4 = sumNumbers.Partial(3, 4);
Console.WriteLine(f4(5));
Again the types of the delegates can be declared with the var keyword.
Official documentation– https://en.wikipedia.org/wiki/Partial_application


6. WeakReference

A weak reference allows the garbage collector to collect an object while still allowing an application to access the object. If you need the object, you can still obtain a strong reference to it and prevent it from being collected.
WeakReferenceTest hugeObject = new WeakReferenceTest();
hugeObject.SharkFirstName = "Sharky";
WeakReference w = new WeakReference(hugeObject);
hugeObject = null;
GC.Collect();
Console.WriteLine((w.Target as WeakReferenceTest).SharkFirstName);
If the garbage collector is not called explicitly, there will be significant chance the weak reference to be still assigned.
Official documentationhttps://msdn.microsoft.com/en-us/library/system.weakreference.aspx

7. Lazy<T>

Use lazy initialization to defer the creation of a large or resource-intensive object, or the execution of a resource-intensive task, particularly when such creation or execution might not occur during the lifetime of the program.
public abstract class ThreadSafeLazyBaseSingleton<T>
    where T : new()
{
    private static readonly Lazy<T> lazy = new Lazy<T>(() => new T());
    
    public static T Instance
    {
        get
        {
            return lazy.Value;
        }
    }
}
Official documentation– https://msdn.microsoft.com/en-us/library/dd642331(v=vs.110).aspx

8. BigInteger

The BigInteger type is an immutable type that represents an arbitrarily large integer whose value, in theory, has no upper or lower bounds. This type differs from the other integral types in the .NET Framework, which have a range indicated by their MinValue and MaxValue properties.
Note: Because the BigInteger type is immutable and because it has no upper or lower bounds, an OutOfMemoryException can be thrown for any operation that causes a BigInteger value to grow too large.
string positiveString = "91389681247993671255432112000000";
string negativeString = "-90315837410896312071002088037140000";
BigInteger posBigInt = 0;
BigInteger negBigInt = 0;

posBigInt = BigInteger.Parse(positiveString);
Console.WriteLine(posBigInt);
negBigInt = BigInteger.Parse(negativeString);
Console.WriteLine(negBigInt);
Official documentationhttps://msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx

9. Undocumented C# Keywords __arglist __reftype __makeref __refvalue

I’m not sure that these can be treated as hidden features of C# because they are undocumented, and you should be careful with them. Probably there isn’t a documentation for a reason. Maybe they are not adequately tested. However, they are colored by the Visual Studio editor and recognized as official keywords.
You can create a typed reference from a variable by using the __makeref keyword. The original type of the variable represented by the typed reference can be extracted using the __reftype keyword. Lastly, the value can be obtained from the TypedReference using the __refvalue keyword. The __arglist has similar behavior to the keyword params- you can access parameters lists.
int i = 21;
TypedReference tr = __makeref(i);
Type t = __reftype(tr);
Console.WriteLine(t.ToString());
int rv = __refvalue( tr,int);
Console.WriteLine(rv);
ArglistTest.DisplayNumbersOnConsole(__arglist(1, 2, 3, 5, 6));
In order to be able to use __arglist you need the ArglistTest class.
public static class ArglistTest
{
    public static void DisplayNumbersOnConsole(__arglist)
    {
        ArgIterator ai = new ArgIterator(__arglist);
        while (ai.GetRemainingCount() > 0)
        {
            TypedReference tr = ai.GetNextArg();
            Console.WriteLine(TypedReference.ToObject(tr));
        }
    }
}
Remarks the ArgIterator object enumerates the argument list starting from the first optional argument, this constructor is provided specifically for use with the C/C++ programming language.
Referencehttp://www.nullskull.com/articles/20030114.asp and  http://community.bartdesmet.net/blogs/bart/archive/2006/09/28/4473.aspx

10. Environment.NewLine

Gets the newline string defined for this environment.
Console.WriteLine("NewLine: {0}  first line{0}  second line{0}  third line", Environment.NewLine);
Official documentationhttps://msdn.microsoft.com/en-us/library/system.environment.newline(v=vs.110).aspx

11. ExceptionDispatchInfo

Represents an exception whose state is captured at a certain point in code. You can use the ExceptionDispatchInfo.Throw method, which can be found in the System.Runtime.ExceptionServices namespace. This method can be used to throw an exception and preserve the original stack trace.
ExceptionDispatchInfo possibleException = null;

try
{
    int.Parse("a");
}
catch (FormatException ex)
{
    possibleException = ExceptionDispatchInfo.Capture(ex);
}

if (possibleException != null)
{
    possibleException.Throw();
}
The caught exception can be thrown again in another method or even in another thread.
Official documentationhttps://msdn.microsoft.com/en-us/library/system.runtime.exceptionservices.exceptiondispatchinfo(v=vs.110).aspx

12. Environment.FailFast()
If you want to exit your program without calling any finally blocks or finalizers use FailFast.
string s = Console.ReadLine();
try
{
    int i = int.Parse(s);
    if (i == 42) Environment.FailFast("Special number entered");
}
finally
{
    Console.WriteLine("Program complete.");
} 
If i equals 42 the finally block won’t be executed.
Official documentationhttps://msdn.microsoft.com/en-us/library/ms131100(v=vs.110).aspx

13. Debug.Assert & Debug.WriteIf & Debug.Indent

Debug.Assert– checks for a condition; if the condition is false, outputs messages and displays a message box that shows the call stack.
Debug.Assert(1 == 0, "The numbers are not equal! Oh my god!");
If the assert fails in Debug mode, the below alert is displayed, containing the specified message.
Debug.WriteIf– writes information about the debug to the trace listeners in the Listeners collection if a condition is true.
Debug.WriteLineIf(1 == 1, "This message is going to be displayed in the Debug output! =)");
Debug.Indent/Debug.Unindent– increases the current IndentLevel by one.
Debug.WriteLine("What are ingredients to bake a cake?");
Debug.Indent();
Debug.WriteLine("1. 1 cup (2 sticks) butter, at room temperature.");
Debug.WriteLine("2 cups sugar");
Debug.WriteLine("3 cups sifted self-rising flour");
Debug.WriteLine("4 eggs");
Debug.WriteLine("1 cup milk");
Debug.WriteLine("1 teaspoon pure vanilla extract");
Debug.Unindent();
Debug.WriteLine("End of list");
If we want to display the ingredients for a cake in the Debug Output Window, we can use the code above.
Official documentation: Debug.AssertDebug.WriteIfDebug.Indent/Debug.Unindent

14. Parallel.For & Parallel.Foreach

I’m not sure if we can add these to the hidden features of C# list because they are heavily used in the TPL (Task Parallel Library). However, I’m listing them here because I like them a lot and utilize their power in my multithreaded applications.
Parallel.For– executes a for loop in which iterations may run in parallel.
int[] nums = Enumerable.Range(0, 1000000).ToArray();
long total = 0;

// Use type parameter to make subtotal a long, not an int
Parallel.For<long>(0, nums.Length, () => 0, (j, loop, subtotal) =>
{
    subtotal += nums[j];
    return subtotal;
},
    (x) => Interlocked.Add(ref total, x)
);

Console.WriteLine("The total is {0:N0}", total);
Interlocked.Add method adds two integers and replaces the first integer with the sum, as an atomic operation.
Parallel.Foreach– executes a foreach (For Each in Visual Basic) operation in which iterations may run in parallel.
int[] nums = Enumerable.Range(0, 1000000).ToArray();
long total = 0;

Parallel.ForEach<int, long>(nums, // source collection
                            () => 0, // method to initialize the local variable
    (j, loop, subtotal) => // method invoked by the loop on each iteration
    {
        subtotal += j; //modify local variable 
        return subtotal; // value to be passed to next iteration
    },
    // Method to be executed when each partition has completed. 
    // finalResult is the final value of subtotal for a particular partition.
(finalResult) => Interlocked.Add(ref total, finalResult));

Console.WriteLine("The total from Parallel.ForEach is {0:N0}", total);
Official documentation: Parallel.For and Parallel.Foreach

15. IsInfinity
Returns a value indicating whether the specified number evaluates to negative or positive infinity.
Console.WriteLine("IsInfinity(3.0 / 0) == {0}.", Double.IsInfinity(3.0 / 0) ? "true" : "false");
Official documentation– https://msdn.microsoft.com/en-us/library/system.double.isinfinity(v=vs.110).aspx


Source Code
You can download the full source code from my Github Repository.

You can check the next part of the series - Top 15 Hidden Features of C# Part 2

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Thursday, September 10, 2015

Developing Android Apps using C#

Developing Android Apps using C#

 

If you love C# and want to create an Android application using that language then you have to thank Xamarin as they created this great Cross Platform development tool which enables developers to develop iOS and Android apps in C# language. I tried developing before in Android but I did not like the experience in using the available IDE, as its slow and resource hungry, so I gave up. A couple of years after that I attended TechEd NZ 2013 and was introduced to this wonderful platform called Xamarin.
Xamarin is offered in different licenses from free to enterprise levels but for not I will be using the starter version which is the free version. It includes the Xamarin Studio which is great start for those who want to try out creating their first apps for Android, they also offer a Business license which lets you develop in Visual Studio so you can use that rich experience similar to developing Web Apps or Windows Apps, then they have this Enterprise which contains everything. For now lets see what the free stuff can offer, I did a simple project which I will be discussing below and it looks very promising, I love it.


 

Like what I said above we will be using the free version so we will make this simple project by using Xamarin Studio. Now I was thinking what to do, I don’t want to create the boring "Hello World!" demo so what I will be developing is a simple calculator which acts like a normal desk calculator. Most of the calculator projects online regardless its C#, VB.Net developed as Windows
forms does not act like a normal desk calculator where you can continuously perform operations and deliver results through the screen, you can’t even change operations along the way, so I decided I will make this one and I accepted my own challenge.
Lets start! First you need to download Xamarin at https://store.xamarin.com/, while installing it will ask you to download as well prerequisites but is you are a developer most or all of them are already set up in your machine.
Once its downloaded you’re ready to roll!
Fire up Xamarin Studio and select new Solution then Android Application, give it a solution name and in this case we use "Calculator".

Once all ok you will see the IDE which is like a cross between Visual Studio and Eclipse, it has intellisense and fancy text colours and highlighting.
 
You will notice if you go to the Resources\layout they the UI is in a file called Main.axml which is a "Hello World" template.

At this point we are more interested on the 2 files on the solution, that layout and the MainActivity.cs where we will be doing our coding.


First lets design you calculator, you need to go to that Main.axml and start coding, you will notice its like Windows form where you can drag and drop items from the Toolbox on the right, it will also have its property window on the bottom left.

Were not interested with the dragging and dropping part so let’s go the code behind (you can control it more), so hit that Source tab below the UI beside the content source. First thing you will notice is that it is in XML format, if you’re so used to drag and drop or HTML coding then you need a bit of learning here specially the layouts.
Common layouts used are Linear Layout, Relative Layout, List View and Grid View. To see how each of them would look like here is an illustration

Linear Layout – you can organize objects in either horizontal or vertical rows.

Relative Layout – specify the location of child objects relative to each other. For example object A is placed on the left of object B or it can be aligned to a parent.

List View – Displays it in a scrolling single column list.


Grid View – Displays it in a scrolling grid view of columns and rows.
Now lets start designing, for this project we will using a mix of Linear and Relative. Copy and Paste the code below then I will give you some explanation of what it does.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
  <EditText
      android:inputType="number"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:id="@+id/resultText" />
  <LinearLayout
android:id="@+id/wrapper0"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/resultText"
android:weightSum="1.0" >
    <Button
        android:text="Clear"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:id="@+id/buttonClear"
        android:layout_weight=".25" />
  </LinearLayout>
  <LinearLayout
android:id="@+id/wrapper1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wrapper0"
android:weightSum="1.0" >
    <Button
        android:text="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:id="@+id/button1" />
    <Button
        android:text="2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button1"
        android:layout_alignTop="@+id/button1"
        android:layout_weight=".25"
        android:id="@+id/button2" />
    <Button
        android:text="3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button2"
        android:layout_alignTop="@+id/button2"
        android:layout_weight=".25"
        android:id="@+id/button3" />
    <Button
        android:text="+"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button3"
        android:layout_alignTop="@+id/button3"
        android:layout_weight=".25"
        android:id="@+id/buttonAdd" />
  </LinearLayout>
  <LinearLayout
android:id="@+id/wrapper2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wrapper1"
android:weightSum="1.0" >
    <Button
        android:text="4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/wrapper2"
        android:layout_weight=".25"
        android:id="@+id/button4" />
    <Button
        android:text="5"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button4"
        android:layout_alignTop="@+id/button4"
        android:layout_weight=".25"
        android:id="@+id/button5" />
    <Button
        android:text="6"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button5"
        android:layout_alignTop="@+id/button5"
        android:layout_weight=".25"
        android:id="@+id/button6" />
    <Button
        android:text="-"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button6"
        android:layout_alignTop="@+id/button6"
        android:layout_weight=".25"
        android:id="@+id/buttonSubtract" />
  </LinearLayout>
  <LinearLayout
android:id="@+id/wrapper3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wrapper2"
android:weightSum="1.0" >
    <Button
        android:text="7"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/wrapper3"
    android:layout_weight=".25"
        android:id="@+id/button7" />
    <Button
        android:text="8"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button7"
        android:layout_alignTop="@+id/button7"
        android:layout_weight=".25"
        android:id="@+id/button8" />
    <Button
        android:text="9"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button8"
        android:layout_alignTop="@+id/button8"
        android:layout_weight=".25"
        android:id="@+id/button9" />
    <Button
        android:text="x"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button9"
        android:layout_alignTop="@+id/button9"
        android:layout_weight=".25"
        android:id="@+id/buttonMultiply" />
  </LinearLayout>
  <LinearLayout
android:id="@+id/wrapper4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wrapper3"
android:weightSum="1.0" >
    <Button
        android:text="(-)"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button7"
        android:layout_weight=".25"
        android:id="@+id/buttonNegative" />
    <Button
        android:text="0"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/buttonNegative"
        android:layout_alignTop="@+id/buttonNegative"
        android:layout_weight=".25"
        android:id="@+id/button0" />
    <Button
        android:text="."
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button0"
        android:layout_alignTop="@+id/buttonNegative"
        android:layout_weight=".25"
        android:id="@+id/buttonDot" />
    <Button
        android:text="/"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/buttonDot"
        android:layout_alignTop="@+id/buttonDot"
        android:layout_weight=".25"
        android:id="@+id/buttonDivide" />
  </LinearLayout>
  <Button
      android:text="="
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_below="@+id/wrapper4"
      android:id="@+id/buttonEquals" />
</RelativeLayout>
Most of the objects are created similar to an HTML tags like and <EditText>. Also like HTML Tags they will have properties and the common ones we used are:
  • orientation – this sets our object orientation either vertical or horizontal.
  • layout_width – fill_parent will fill depending on the parent with, you can also specify a with by using something like 200dp. If you want to use percentage use 0dp but we will be indicating percentage on layout_weight.
  • layout_height – similar to layout_width.
  • layout_weight – this indicated the percentage you will use on the width.
  • id – identifier to the object.
  • layout_toRightOf – this indicates you will place this object to the right of what object Id.
  • layout_alignTop – this aligns your object similar to what object Id.
  • layout_below – this will place your object below the object Id.
other elements would sound similar to .Net object properties. Now click your content tab to see how it looks. It should be something like this

Now you have your UI, you need to start coding in C#, so go to your MainActivity.cs
To display the layout you need to do this.
SetContentView (Resource.Layout.Main);
Then you will notice that objects are not natively available in code, you cant do something like this
resultText.Text = "";
you need to find it like how you find objects but ID in a grid during the ASP.Net days. To do it here is a sample for button1
Button button1 = FindViewById<Button> (Resource.Id.button1);
Now you have your button1, you can assign a delegate and define what it should do when you click
button1.Click += delegate {
//Your stuff here
};
Other than that you’re good to go, everything should be easy. So for the full code just copy and paste the one below, it’s an operational calculator.
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace SampleAndroidApp
{
    [Activity(Label = "Ray's Calculator", MainLauncher = true)]
    public class MainActivity : Activity
    {
        private enum Operation { Addition, Subtraction, Division, Multiplication };
        private enum LastKeyInput { Digit, Operator, Equal, DecimalPoint, Sign }

        decimal? digitMemory = null;
        decimal? totalMemory = null;

        Operation? operationMemory = null;

        LastKeyInput? lastKeyInput = LastKeyInput.Digit;

        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 button1 = FindViewById(Resource.Id.button1);
            Button button2 = FindViewById(Resource.Id.button2);
            Button button3 = FindViewById(Resource.Id.button3);
            Button button4 = FindViewById(Resource.Id.button4);
            Button button5 = FindViewById(Resource.Id.button5);
            Button button6 = FindViewById(Resource.Id.button6);
            Button button7 = FindViewById(Resource.Id.button7);
            Button button8 = FindViewById(Resource.Id.button8);
            Button button9 = FindViewById(Resource.Id.button9);
            Button button0 = FindViewById(Resource.Id.button0);
            Button buttonDot = FindViewById(Resource.Id.buttonDot);
            Button buttonNegative = FindViewById(Resource.Id.buttonNegative);

            EditText resultText = FindViewById(Resource.Id.resultText);

            Button buttonAdd = FindViewById(Resource.Id.buttonAdd);
            Button buttonSubtract = FindViewById(Resource.Id.buttonSubtract);
            Button buttonMultiply = FindViewById(Resource.Id.buttonMultiply);
            Button buttonDivide = FindViewById(Resource.Id.buttonDivide);
            Button buttonEquals = FindViewById(Resource.Id.buttonEquals);
            Button buttonClear = FindViewById(Resource.Id.buttonClear);

            buttonNegative.Click += delegate
            {
                //handles if negative sign is the first input after calculation
                if (lastKeyInput != LastKeyInput.Digit && lastKeyInput != LastKeyInput.DecimalPoint && lastKeyInput != LastKeyInput.Sign)
                {
                    resultText.Text = "-";
                    lastKeyInput = LastKeyInput.Sign;
                    return;
                }
                //handles multiple negative sign
                if (!resultText.Text.Contains("-"))
                {
                    resultText.Text = "-" + digitMemory.ToString();
                    lastKeyInput = LastKeyInput.Sign;
                }

            };
            buttonDot.Click += delegate
            {
                //handles if decimal point is the first input after calculation
                if (lastKeyInput != LastKeyInput.Digit && lastKeyInput != LastKeyInput.DecimalPoint && lastKeyInput != LastKeyInput.Sign)
                {
                    resultText.Text = ".";
                    lastKeyInput = LastKeyInput.DecimalPoint;
                    return;
                }
                //handles multiple decimal point
                if (!resultText.Text.Contains("."))
                {
                    resultText.Text = digitMemory.ToString() + ".";
                    lastKeyInput = LastKeyInput.DecimalPoint;
                }

            };
            button1.Click += delegate
            {
                //Renders Text on Screen
                RenderCurrentValue(resultText.Text, "1");
                resultText.Text = digitMemory.ToString();

                //Perform calculation based on current operator
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button2.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "2");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button3.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "3");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button4.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "4");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button5.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "5");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button6.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "6");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button7.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "7");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button8.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "8");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button9.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "9");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            button0.Click += delegate
            {
                RenderCurrentValue(resultText.Text, "0");
                resultText.Text = digitMemory.ToString();
                Calculate();
                lastKeyInput = LastKeyInput.Digit;
            };

            buttonClear.Click += delegate
            {
                resultText.Text = "";
                ResetMemory();
            };

            buttonAdd.Click += delegate
            {
                if (lastKeyInput == LastKeyInput.Digit || lastKeyInput == LastKeyInput.Operator)
                {
                    operationMemory = Operation.Addition;
                }
                resultText.Text = totalMemory.ToString();
                lastKeyInput = LastKeyInput.Operator;
            };

            buttonSubtract.Click += delegate
            {
                if (lastKeyInput == LastKeyInput.Digit || lastKeyInput == LastKeyInput.Operator)
                {
                    operationMemory = Operation.Subtraction;
                }
                resultText.Text = totalMemory.ToString();
                lastKeyInput = LastKeyInput.Operator;
            };

            buttonMultiply.Click += delegate
            {
                if (lastKeyInput == LastKeyInput.Digit || lastKeyInput == LastKeyInput.Operator)
                {
                    operationMemory = Operation.Multiplication;
                }
                resultText.Text = totalMemory.ToString();
                lastKeyInput = LastKeyInput.Operator;
            };

            buttonDivide.Click += delegate
            {
                if (lastKeyInput == LastKeyInput.Digit || lastKeyInput == LastKeyInput.Operator)
                {
                    operationMemory = Operation.Division;
                }
                resultText.Text = totalMemory.ToString();
                lastKeyInput = LastKeyInput.Operator;
            };

            buttonEquals.Click += delegate
            {
                lastKeyInput = LastKeyInput.Equal;
                resultText.Text = totalMemory.ToString();
                ResetMemory();
            };

        }

        private void Calculate()
        {
            if (operationMemory != null)
            {
                switch (operationMemory)
                {
                    case Operation.Addition:
                        if (totalMemory == null)
                        {
                            //Handles first entry
                            totalMemory = digitMemory;
                        }
                        else
                        {
                            totalMemory = totalMemory + digitMemory;
                        }
                        lastKeyInput = LastKeyInput.Operator;
                        break;

                    case Operation.Subtraction:
                        if (totalMemory == null)
                        {
                            //Handles first entry
                            totalMemory = digitMemory;
                        }
                        else
                        {
                            totalMemory = totalMemory - digitMemory;
                        }
                        lastKeyInput = LastKeyInput.Operator;
                        break;

                    case Operation.Multiplication:
                        if (totalMemory == null)
                        {
                            //Handles first entry
                            totalMemory = digitMemory;
                        }
                        else
                        {
                            totalMemory = totalMemory * digitMemory;
                        }
                        lastKeyInput = LastKeyInput.Operator;
                        break;

                    case Operation.Division:
                        if (totalMemory == null)
                        {
                            //Handles first entry
                            totalMemory = digitMemory;
                        }
                        else
                        {
                            totalMemory = totalMemory / digitMemory;
                        }
                        lastKeyInput = LastKeyInput.Operator;
                        break;
                }
            }
            else
            {

                totalMemory = digitMemory;

            }
        }

        private void RenderCurrentValue(string currentRenderedValue, string character)
        {
            //display multiple digits
            if (lastKeyInput == LastKeyInput.Digit || lastKeyInput == LastKeyInput.DecimalPoint || lastKeyInput == LastKeyInput.Sign)
            {
                digitMemory = decimal.Parse(currentRenderedValue + character);
            }
            else
            {
                digitMemory = decimal.Parse(character);
            }
        }

        private void ResetMemory()
        {
            totalMemory = null;
            digitMemory = null;
            operationMemory = null;
            lastKeyInput = LastKeyInput.Digit;
        }
    }

}
Just a side note : You might notice Calculate happens on each digit press, this makes sure you have a running total even before you hit the operator. The operator buttons will just store the current operator needed for your next digit press.
Other than that you are now all good to go, just hit run

It will now ask you for a device, if you don’t have an emulator yet then you can create one, choose create emulator then hit OK.

Click New

Then I suggest create something similar to a device you have, so you can play around with it on your device.

Once created hit start, then launch

You will now see it will start, and it will also show you any errors it encounter.

Once started go back to Xamarin and choose the device you want your app to run on, in this case your newly created emulator, it will then be automatically deployed on the emulator.

You will then see the progress on the middle top part of the IDE.

Then on your emulator

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Wednesday, September 9, 2015

MVC4 Mobile Friendly Web Applications

MVC4 Mobile Friendly Web Applications


 



Introduction


A few years ago, mobile web sites were more of an after-thought for many developers unless you were involved in developing apps specifically targeted for mobile devices. I was surprised to read on wiki that it was only March 2010 when Apple began taking pre-orders for the iPad. What a different landscape we have seen since. Desktops, Tablet and Mobile support are now a major design goal for any site that needs a broad reach and this is only set to increase.
This article will demonstrate how MVC4, almost out of the box allows us to deliver views that cater for specific mobile devices and keep the code base shared as much as possible, creating mobile friendly web applications.

Sample Application

The sample web application for this article uses MVC 4, Microsoft’s latest web development platform and Visual Studio 2012.

This article will walk through some fairly simple steps to mobile enable the ‘Internet Application’ template. By running the application, you will be able to send requests for the home page which targets a Desktop, iPad and iPhone either by using different devices to view the application or by sending a different User Agent string as explained in the article. The code supports Desktop, iPad and iPhone as examples of how to support mobile devices.

Background

There are a number of popular approaches for designing mobile sites including Dedicated sites and Responsive Design and in MVC4 the 'Mobile Website' template.
Dedicated sites for mobile and separate sites for desktops. One of the problems with this model is the maintenance of two (if not three) different sites.
Responsive Design where the site gets designed with stylesheets that adapt to screen size and available screen real-estate. When deciding on a responsive design model, the choice needs to be made as to whether to start with a mobile site and then perform progressive enhancement or whether to start with the desktop design and do graceful degradation, each of which has its own design challenges. Added to this is the need to cater for mobile devices with typically lower bandwidth and less visible content, where this can often lead to downloading less optimal pages over capped download limits.
MVC4 Mobile Website Template: When I first installed the preview release of MVC4, I was drawn to the new ‘mobile’ template. I was quite impressed as JQuery and JQuery mobile where baked in and it performed pretty well. It soon became apparent though that this was specifically a mobile orientated site and not suitable for the desktop.

Considering Layout

When designing for the mobile platform, some obvious differences exist with available real-estate. This commonly leads to single column layouts for mobiles, multi column layouts for desktops and something in the middle for tablets. As you start designing a mobile friendly site, it soon becomes apparent that to we are dealing with Small, Medium and Large layouts.

Creating the Web application

Choosing the “Internet Application” template gives us a site that is primarily optimised for the desktop. We will start by creating our mobile friendly site here as shown below.

After building and running this boiler plate site, results for a desktop and mobile can be seen below.

After re-sizing the browser window, the page re-flowed based on a responsive container.
The reason why this works is because of the following code snippet found in the layout file _Layout.cshtml.
<meta name="viewport" content="width=device-width" />
The webkit based browsers found in the majority of mobile phones will automatically attempt to reflow the page if this tag is present. Not too much work for a fairly impressive result. Still some way to go though for a truly mobile experience.

Detecting Mobile Devices

Time to enable our site to detect requests made to our site from different mobile devices. We are going to do this by examining the User Agent string and make decisions based on this understanding.
We will add a new method to our Global.asax.cs file that gets called in the method Application_Start() and name it EvaluateDisplayMode.
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AuthConfig.RegisterAuth();
    /* Boilerplate code above... */
    EvaluateDisplayMode(); //Evaluate incoming request and update Display Mode table
}
The EvaluateDisplayMode() method itself.
/// <summary>
/// Evaluates incoming request and determines and adds an entry into the Display mode table
/// </summary>
private static void EvaluateDisplayMode()
{
    DisplayModeProvider.Instance.Modes.Insert(0,
        new DefaultDisplayMode("Phone")
        {  //...modify file (view that is served)
           //Query condition
            ContextCondition = (ctx => (
                //look at user agent
                (ctx.GetOverriddenUserAgent() != null) &&
                (//...either iPhone or iPad                           
                    (ctx.GetOverriddenUserAgent().IndexOf("iPhone", StringComparison.OrdinalIgnoreCase) >= 0) ||
                    (ctx.GetOverriddenUserAgent().IndexOf("iPod", StringComparison.OrdinalIgnoreCase) >= 0)
                )
        ))
        });
    DisplayModeProvider.Instance.Modes.Insert(0,
        new DefaultDisplayMode("Tablet")
        {
            ContextCondition = (ctx => (                     
                (ctx.GetOverriddenUserAgent() != null) &&
                (                            
                    (ctx.GetOverriddenUserAgent().IndexOf("iPad", StringComparison.OrdinalIgnoreCase) >= 0) ||
                    (ctx.GetOverriddenUserAgent().IndexOf("Playbook", StringComparison.OrdinalIgnoreCase) >= 0)
                )
        ))
        });
}
The code evaluates the User Agent string and if it finds a match for an ‘iPad’ or ‘Playbook’ it adds an entry into the DisplayModes table for a ‘Tablet’. It also performs checks for an iPhone or iPod and sets the ‘Phone’ DisplayMode, respectively. In the case of a desktop, currently this is the default so no need to add anything else at the moment. You can see how easy it would be to add additional devices and the code could be refactored further.
Note* There are obviously other frameworks geared specifically to identifying requests to ascertain the client device but this method works with all the common device types I have come across for mass market coverage. What you do have here is a point in the pipeline to perform the necessary checks.

Delivering Device Specific Views

As a result of the Display Modes table having been updated from the detection above, the MVC engine will then modify the view it was going to serve, to match the mobile device request if available.
The table below shows examples of views that will be served if available based on the User Agent.
DeviceClient RequestView
PC /YourMVCApp/Home
(controller)
Index.cshtml
iPad/YourMVCApp/Home (controller)Index.Tablet.cshtml
iPhone/YourMVCApp/Home (controller)Index.Phone.cshtml
Well that’s a leap forward , we can now easily create a unique view based on different devices!
The Visual Studio 2012 Solution explorer screen shot below shows the views we created to support the new devices.

Testing what we have so far...

Although there is no substitute for testing on a hardware mobile device, during initial development, Safari makes it easy to send a request to the server with a specific user agent. You can also add your own User Agent strings for devices not available out of the box with Safari using Safari to send a specific User Agent.
You can set a new User agent string via Menu->Develop->User Agent. The Safari screen shot below shows the User Agent string being set for a request.

Note**
If you cannot see the ‘Develop’ menu, enable it via Settings -> Preferences -> Advanced and tick ‘Show Develop menu in menu bar’
It’s quite re-assuring to see this working and already at this point we have some reasonable control over the views we can render/return back to the client.

Enhancing our Mobile View

Although we have made good progress, our mobile views still leave a lot to be desired. We could just amend our mobile view at this point and in some circumstances that would be appropriate. We will take it one step further and create Layout pages for each of our device types as can be seen below.

Now we have the Layout pages in place, we need to update our views to use them.
@{
ViewBag.Title = "Tablet";
Layout = "../Shared/_Layout.Tablet.cshtml";
}
You can see we are also setting the title so that we can easily identify the current view in the title bar of the browser.

Adding Mobile scripts

Microsoft have fully embraced jQuery and jQuery Mobile now which is great. Because we started with the ‘Internet Application’ template, jQuery Mobile is not included so we will go ahead and include it via the ‘Package Manager’. Right click the solution and select ‘Package Manager’ (this can also be done via the cmd line if you prefer).
The screenshot below shows the package manager after we entered and selected JQuery Mobile.

Once this is added, we will see scripts and stylesheets added to ‘Scripts’ and ‘Content’ respectively as shown below in Solution Explorer.

Enabling Mobile scripts

Although we now have the mobile scripts available, we still need to reference them in our mobile views. The release of MVC4 Bundles appears to work well now for scripts and stylesheets. We will add our new mobile scripts and stylesheets to the bundling tables with the following entries inside the ‘RegisterBundles’ method located in ‘BundleConfig.cs’ in the ‘App_Start’ Solution folder.
bundles.Add(new StyleBundle("~/Content/mobilecss").Include("~/Content/jquery.mobile*"));
bundles.Add(new ScriptBundle("~/bundles/jquerymobile").Include("~/Scripts/jquery.mobile*"));
Now the scripts and stylesheets have been added to the bundling tables, we can utilise them inside our views by adding a render call in the _Layout.Mobile.cshtml head section as show below.
<head>
@Styles.Render("~/Content/mobileCss", "~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>

Styling the mobile views with jQuery mobile

Although styling the mobile view with JQuery Mobile is beyond the scope of this article, I went ahead and added a little just to get our views looking differently.

Folowing convention (a touch of refactoring)

As we have added code to our Global.asax 'Application_Start()', it makes sense to extract our current 'EvaluateDisplayMode()' into it's own Device configuration, so that as it grows, it doesn't bloat the view of startup and makes it more maintainable. The other configuration classes reside in the 'App_Start' solution folder and we will use the same convention and create a static 'DeviceConfig' class as shown below.

This enables us to reduces our device evaluation to one line in 'Application_Start()' as shown below.
DeviceConfig.EvaluateDisplayMode(); //Evaluate incoming request and update Display Mode table
This now fits in with the convention of the other configuration classes. (Maybe we will see something like this in the next release of MVC)
The new DeviceConfig class can be seen below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.WebPages;
namespace MvcDesktop
{
    /// <summary>
    /// Device specific startup configuration
    /// </summary>
    public static class DeviceConfig
    {
        const string DeviceTypePhone = "Phone";               
        const string DeviceTypeTablet = "Tablet";
        /// <summary>
        /// Evaluates incoming request and determines device.
        /// Adds an entry into the Display mode table
        /// </summary>
        public static void EvaluateDisplayMode()
        {
  //... refactored code here, similar to before...
 }            
    }
} 

Limitations

  • We did not add any web application tags or media queries to enhance our decisions when rendering views.
  • We would in practice leverage more partial and shared views to ensure the content could be managed centrally in a real world project.
  • The sample project only affects the Home page for the three devices.

Final Results

Our home page when requested by a Mobile, Tablet or Desktop can be seen below.
Mobile View

Tablet View

Desktop View

Conclusion

The separation of views for different device scenarios is certainly a model which sits comfortably with an MVC developer like myself and can if approached carefully, lead to very light weight views being served to mobile devices.
If you already possess MVC skills and spend most of your time developing for the Microsoft platform, the new MVC baked in support for mobile devices is the best we have had up to now. Of course you could have achieved the same in MVC3 but with a bit more work.


About the Author


Carl Randall
Architect AssemblySoft
United Kingdom United Kingdom
Carl Randall has specialized in Information Technology solutions for over 15 years. Specializing in full life-cycle development projects for both enterprise-wide systems, desktop applications and Internet based solutions.

Carl has been involved in .Net since it's inception and is currently a Microsoft Certified Professional Developer (Enterprise).

When not coding and designing, Carl enjoys playing table tennis, tennis, sailing and spending time by the beach - when the british weather permits Wink | ;)