C# and multicultural IsDate() and ToDate()

C# does not provide IsDate() function. Sometimes in your developer environment region settings are different from the live environment. In my case, I don’t know what region settings there are in my company servers.

For this reason, I created a function to check is a string is a date in a culture and to convert a string to a date.

/// 
/// Determines whether the specified text is date.
/// 
/// The text.
/// 
/// true if the specified text is date; 
/// otherwise, false.
/// 
public static bool IsDate(this string text)
{
    if (!string.IsNullOrEmpty(text))
    {
        DateTime result = DateTime.MinValue;
        foreach (CultureInfo cultureInfo in 
                 CultureInfo.GetCultures(CultureTypes.AllCultures))
        {
            try
            {
                if (DateTime.TryParse(text, cultureInfo, 
                                      DateTimeStyles.None, 
                                      out result))
                    return true;
            }
            catch (Exception ex) { }
        }
    }

    return false;
}

/// 
/// To the date.
/// 
/// The text.
/// System.Nullable<DateTime>.
public static DateTime? ToDate(this string text)
{
    if (!string.IsNullOrEmpty(text))
    {
        DateTime result = DateTime.MinValue;
        foreach (CultureInfo cultureInfo in 
                 CultureInfo.GetCultures(CultureTypes.AllCultures))
        {
            try
            {
                if (DateTime.TryParse(text, cultureInfo, 
                                      DateTimeStyles.None, 
                                      out result))
                    return result;
            }
            catch (Exception ex) { }
        }
    }

    return null;
}

Happy coding!

Render in MVC a link with image and text

Hi guys, I want in MVC to render a text with an image as an ActionLink. For creating a simple anchor tag, we use Html.ActionLink() helper which generates anchor tag for us.

If you want to create something a bit more complicated, you must create you own component. For this reason, I created the following code. It allows you to create an anchor with an image and a text.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace PSC.MVC.Helpers
{
    public static class CustomHtmlHelpers
    {
        /// 
        /// Enum ImageAndText
        /// 
        public enum ImageAndText
        {
            /// 
            /// Image on the left, text on the right
            /// 
            ImageOnTheLeft,

            /// 
            /// Text on the left, image on the right
            /// 
            ImageOnTheRight
        }

        /// 
        /// Images the action link.
        /// 
        /// The HTML helper.
        /// The link text.
        /// The action.
        /// The controller.
        /// The route values.
        /// The HTML attributes.
        /// The image source.
        /// The alternate text.
        /// The text style.
        /// The image style.
        /// The image position.
        /// IHtmlString.
        public static IHtmlString ImageActionLink(
               this HtmlHelper htmlHelper, string linkText, string action, 
               string controller, object routeValues, object htmlAttributes, 
               string imageSrc, string alternateText = "", 
               string textStyle = "", string imageStyle = "", 
               ImageAndText imagePosition = ImageAndText.ImageOnTheLeft)
        {
            var urlHelper = new UrlHelper(
                    htmlHelper.ViewContext.RequestContext);

            // create the image
            var img = new TagBuilder("img");
            img.Attributes.Add("src", 
                    VirtualPathUtility.ToAbsolute(imageSrc));
            if (!string.IsNullOrEmpty(alternateText))
                img.Attributes.Add("alt", alternateText.Trim());
            if (!string.IsNullOrEmpty(imageStyle))
                img.Attributes.Add("style", imageStyle);

            // create a render for the image and the text
            string render = "";
            if (imagePosition == ImageAndText.ImageOnTheLeft)
                render = img.ToString(TagRenderMode.SelfClosing) + linkText;
            else
                render = linkText + img.ToString(TagRenderMode.SelfClosing);

            // create the anchor with image and text
            var anchor = new TagBuilder("a") {
                InnerHtml = render
            };
            if (!string.IsNullOrEmpty(textStyle))
                anchor.AddCssClass(textStyle);

            // add reference to the anchor
            anchor.Attributes["href"] = urlHelper.Action(action, 
                                                         controller, 
                                                         routeValues);
            anchor.MergeAttributes(new RouteValueDictionary(htmlAttributes));

            return MvcHtmlString.Create(anchor.ToString());
        }
    }
}

In your MVC code you have to add:

@using PSC.MVC.Helpers;

and then you can call your component:
@Html.ImageActionLink("Your text", "Index", "Home", null, null, 
                      "~/Content/images/img.png", "Logo", "navbar-brand", 
                      "width: 40px;")

A Simple Speedtest Application for Xamarin

In my previous post I described how to check your connection in a C# project. I should have the same function in a PCL project for Xamarin. Based on my project, I created this function:
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace PSC.Xamarin.Connection
{
	/// 
	/// Speed test.
	/// 
	public class SpeedTest
	{
		public double SecondsForOneMb { get; set; } = 0;
		public double KbSeconds { get; set; } = 0;

		/// 
		/// Starts the test to download a file from an url.
		/// Read SecondsForOneMb and KbSeconds for the result
		/// 
		public async Task StartTest()
		{
			string url = 
            "http://puresourcecode.com/file.axd?file=/SpeedTest/1024kb.txt";
			HttpClient client = new HttpClient();

			// get current tickcount 
			double starttime = Environment.TickCount;

			// download file from the specified URL, 
			// and save it to C:\speedtest.txt
			// in your project change the path of the following line
			var httpResponse = await client.GetAsync(url);
			byte[] dataBuffer = 
                   await httpResponse.Content.ReadAsByteArrayAsync();

			// get current tickcount
			double endtime = Environment.TickCount;

			// how many seconds did it take?
			// we are calculating this by subtracting starttime from
			// endtime and dividing by 1000 (since the tickcount is in 
			// miliseconds 1000 ms = 1 sec)
			SecondsForOneMb = Math.Floor(endtime - starttime) / 1000;

			// calculate download rate in kb per sec.
			// this is done by dividing 1024 by the number of seconds it
			// took to download the file (1024 bytes = 1 kilobyte)
			KbSeconds = Math.Round(1024 / SecondsForOneMb);
		}
	}
}

Happy coding!

A Simple Speedtest Application

The purpose of this code is the detect how slow is your connection downloading a file from a site. First of all, you have to create a file with a known size: for that you can use fsutil in the prompt (see another post in this blog for info).

When yo do put your file in a webserver (or you can use my url), we can create the code to check the connection speed.

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;

namespace SpeedTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "A simple speed test connection for your app";

            // the URL to download a file from
            Uri URL = new Uri(
            "http://puresourcecode.com/file.axd?file=/SpeedTest/1024kb.txt"
            );
            WebClient wc = new WebClient();

            Console.WriteLine("Simple speedtest");
            Console.WriteLine("----------------");
            Console.WriteLine("Will test your download rate. " + 
                              "Press any key to begin.");
            Console.ReadKey();

            Console.WriteLine("\nDownloading file: 1024kb.txt...");
            Console.WriteLine("From http://puresourcecode.com");
            Console.WriteLine("Note: This file will automatically " + 
                              "be deleted after the test.");

            // get current tickcount 
            double starttime = Environment.TickCount;

            // download file from the specified URL, 
            // and save it to C:\speedtest.txt
            // in your project change the path of the following line
            wc.DownloadFile(URL, @"C:\speedtest.txt");

            // get current tickcount
            double endtime = Environment.TickCount;

            // how many seconds did it take?
            // we are calculating this by subtracting starttime from
            // endtime and dividing by 1000 (since the tickcount is in 
            // miliseconds 1000 ms = 1 sec)
            double secs = Math.Floor(endtime - starttime) / 1000;

            // calculate download rate in kb per sec.
            // this is done by dividing 1024 by the number of seconds it
            // took to download the file (1024 bytes = 1 kilobyte)
            double kbsec = Math.Round(1024 / secs);

            Console.WriteLine("\nCompleted. Statistics:\n");

            Console.WriteLine("1mb download: \t{0} secs", secs);
            Console.WriteLine("Download rate: \t{0} kb/sec", kbsec);

            Console.WriteLine("\nPress any key to exit...");
            Console.Read();
            Console.WriteLine("Deleting file...");
            try
            {
                // delete downloaded file
                System.IO.File.Delete(@"C:\speedtest.txt");
                Console.WriteLine("Done.");
            }
            catch
            {
                Console.WriteLine("Couldn't delete download file.");
                Console.WriteLine("To delete the file yourself.");
                Console.ReadKey();
            }
        }

    }
}

Happy coding!

$.ajax No 'Access-Control-Allow-Origin' header is present on the requested resource with WebAPI

I want to get data from a WebAPI with jquery

        $("#btnSend").click(function () {
            $("#sending").show();
            $.ajax({
                type: 'GET',
                url: '/Report/SendEmail?quote=18',
                crossDomain: true,
                success: function (msg) {
                    if (msg == 'True') {
                        alert('Email sent to the client');
                    }
                    $("#sending").hide();
                },
                error: function (request, status, error) {
                    $("#sending").hide();
                }
            });
        });

and it produce

‘No Access-Control-Allow-Origin' header is present on the requested resource error.

The solution is to add in the result of the WebAPI the following code:

            Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST");
            Response.Headers.Add("Access-Control-Allow-Headers", "accept, authority");
            Response.Headers.Add("Access-Control-Allow-Credentials", "true");

Happy coding!

Xamarin Forms and Google Mobile Ads for iOS

If you have a new Xamarin Project and you want to add an advertising, the simple way it is to use Google Admob. This implementation is only for Android and iOS.

One of the first things people think about when developing for a new platform / using a new technology is monetization; and in my case the question is: how easy is it to integrate AdMob? For Xamarin Forms the answer would be: “It depends” – it depends on luck & on the complexity of what you want to achieve; but I will detail this as we move along.

The first thing you need to do is add the required components to your projects. For this walktrough I will be using Visual Studio but it should be relatively the same when using Xamarin Studio. Here, things go separate ways for each of the platforms:

  • for Android – add the Google Play Services component
  • for iOS – add the AdMob component
  • for Windows Phone – download the SDK from here and add it as a reference

By now, you Android project should no longer be building & you should be receiving a COMPILETODALVIK : UNEXPECTED TOP-LEVEL error. To fix that, go into your Droid project properties, select the Android Options tab and then under Advanced modify the value for the Java Max Heap Size to 1G. Your project should now build without any errors.

Next, inside your shared / PCL project add a new Content View and call it AdMobView. Remove the code generated inside it’s constructor & it should look like this:

public class AdMobView : ContentView
{
    public AdMobView() { }
}

Add this new view to your page. In XAML you can do it like this:

<controls:AdMobView WidthRequest="320" HeightRequest="50" />

Make sure NOTHING interferes with the control. By nothing I mean – overlapping controls, page padding, control margins / spacing, etc. If you have something overlapping the ad control, ads will not display & you won’t receive an error, so be careful.

Android

Add a new class called AdMobRenderer with the code below. Make sure to keep the ExportRenderer attribute above the namespace, otherwise the magic won’t happen.

using WordBankEasy.Droid.Renderers;
using WordBankEasy.Views.AdMob;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(AdMobView), typeof(AdMobRenderer))]

namespace WordBankEasy.Droid.Renderers {
    public class AdMobRenderer : ViewRenderer<AdMobView, Android.Gms.Ads.AdView> {
        protected override void OnElementChanged(ElementChangedEventArgs<AdMobView> e) {
            base.OnElementChanged(e);

            if (Control == null) {
                var ad = new Android.Gms.Ads.AdView(Forms.Context);
                ad.AdSize = Android.Gms.Ads.AdSize.Banner;
                ad.AdUnitId = "ca-app-pub-4381168884554284/2250461656";

                var requestbuilder = new Android.Gms.Ads.AdRequest.Builder();
                ad.LoadAd(requestbuilder.Build());

                SetNativeControl(ad);
            }
        }
    }
}

Next, you need to modify your AndroidManifest.xml file to add the AdActivity & required permissions for displaying ads: ACCESS_NETWORK_STATE, INTERNET; just like in the example below (see also http://puresourcecode.com/dotnet/post/Android-required-permissions).

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-sdk android:minSdkVersion="15" />
    <application>
    <activity android:name="com.google.android.gms.ads.AdActivity" 
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:theme="@android:style/Theme.Translucent" />
    </application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

That’s it. Your Android build should now display ads inside the AdMobView content view.

iOS

This, I haven’t got the chance to test yet as I don’t have a Mac around but people say it works, so I’ve added it for reference. Same as before, just add a new class called AdMobRenderer and copy-paste the code below but before you have to add a component.

In your iOS project click on “Components” (as in the picture)

Components

and click on “Get More Components…”. Then search admob and install it.

Google-Admob-Xamarin

using Xamarin.Forms;
using CoreGraphics;
using Xamarin.Forms.Platform.iOS;
using UIKit;
using WordBankEasy.Views.AdMob;
using WordBankEasy.iOS.Renderers;
using Google.MobileAds;

[assembly: ExportRenderer(typeof(AdMobView), typeof(AdMobRenderer))]
namespace WordBankEasy.iOS.Renderers {
    public class AdMobRenderer : ViewRenderer {
        const string AdmobID = "ca-app-pub-4381168884554284/5843056458";

        BannerView adView;
        bool viewOnScreen;

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e) {
            base.OnElementChanged(e);

            if (e.NewElement == null)
                return;

            if (e.OldElement == null) {
                adView = new BannerView(size: AdSizeCons.Banner, origin: new CGPoint(-10, 0)) {
                    AdUnitID = AdmobID,
                    RootViewController = UIApplication.SharedApplication.Windows[0].RootViewController
                };

                adView.AdReceived += (sender, args) => {
                    if (!viewOnScreen) this.AddSubview(adView);
                    viewOnScreen = true;
                };

                adView.LoadRequest(Request.GetDefaultRequest());
                base.SetNativeControl(adView);
            }
        }
    }
}

Here you can receive an strange error like:

Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[AppDelegate window]: unrecognized selector sent to instance 0x7ffee9cdd4d0

Native stack trace:

0 CoreFoundation 0x000000010a12ed85 __exceptionPreprocess + 165

1 libobjc.A.dylib 0x000000010a5e3deb objc_exception_throw + 48

2 CoreFoundation 0x000000010a137d3d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205

3 CoreFoundation 0x000000010a07db17 forwarding + 487

4 CoreFoundation 0x000000010a07d8a8 _CF_forwarding_prep_0 + 120

5 WordBankEasyiOS 0x0000000100bc65e4 GADiTunesMetadataForFileAtPath + 4181

6 WordBankEasyiOS 0x0000000100c2d484 hasRequiredParams + 10260

7 WordBankEasyiOS 0x0000000100bc5f06 GADiTunesMetadataForFileAtPath + 2423

8 WordBankEasyiOS 0x0000000100bc1c35 GADCategories_NSURL_GADNSURLUtilities + 4438

9 WordBankEasyiOS 0x0000000100c00fde GADDispatchAsyncSafeMainQueue + 45

10 libobjc.A.dylib 0x000000010a5e4bff _class_initialize + 679

11 libobjc.A.dylib 0x000000010a5eacc5 lookUpImpOrForward + 176

12 libobjc.A.dylib 0x000000010a5f98bb objc_msgSend + 187

13 WordBankEasyiOS 0x0000000100bbe0ff GADCategories_DFPBannerView_CustomRenderedAd + 18074

14 WordBankEasyiOS 0x0000000100bbe382 GADCategories_DFPBannerView_CustomRenderedAd + 18717

15 WordBankEasyiOS 0x0000000100bbe527 GADCategories_DFPBannerView_CustomRenderedAd + 19138

16 ??? 0x000000011d368a0e 0x0 + 4785080846

17 ??? 0x000000011d36843b 0x0 + 4785079355

18 ??? 0x000000011d364d88 0x0 + 4785065352

19 ??? 0x000000011c51bbd6 0x0 + 4770085846

20 ??? 0x000000011c51b138 0x0 + 4770083128

21 ??? 0x000000011c51b138 0x0 + 4770083128

22 ??? 0x000000011c51b138 0x0 + 4770083128

Don't worry! I received the same error and I spend a lot of time to understand and fix it. There is a workaround that seems working fine.

In your iOS project, open AppDelegate.cs and add this code:

/// <summary>
/// Gets the window.
/// </summary>
/// <returns>UIWindow.</returns>
[Export("window")]
public UIWindow GetWindow() {
   return UIApplication.SharedApplication.Windows[0];
}

A complete example of this class is:

using System;
using System.Collections.Generic;
using System.Linq;

using Foundation;
using ImageCircle.Forms.Plugin.iOS;
using UIKit;

namespace WordBankEasy.iOS {
    // The UIApplicationDelegate for the application. This class is responsible for launching the 
    // User Interface of the application, as well as listening (and optionally responding) to 
    // application events from iOS.
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate {
        //
        // This method is invoked when the application has loaded and is ready to run. In this 
        // method you should instantiate the window, load the UI into it and then make the window
        // visible.
        //
        // You have 17 seconds to return from this method, or iOS will terminate your application.
        //
        public override bool FinishedLaunching(UIApplication app, NSDictionary options) {
            global::Xamarin.Forms.Forms.Init();

            ImageCircleRenderer.Init();

            LoadApplication(new App());

            return base.FinishedLaunching(app, options);
        }

        /// <summary>
        /// Gets the window.
        /// </summary>
        /// <returns>UIWindow.</returns>
        [Export("window")]
        public UIWindow GetWindow() {
            return UIApplication.SharedApplication.Windows[0];
        }
    }
}

After that you can start you app and see you advertising without problem. For now :)

Happy coding!

How to update the data in listview in Xamarin.Forms?

First you add a new class as a ViewModel like:

public class RoomViewModel : BaseViewModel
{
   [here following code]
}

If you don't have BaseViewModel try to download from nuget Refractored.MvvmHelpers. Then in your class define an observable collection like

  public ObservableCollection<RoomRecommandation> _roomSuggestionList = 
               new ObservableCollection<RoomRecommandation>();
  
  public ObservableCollection<RoomRecommandation> Recommendations
  {
     get { return _roomSuggestionList; }
  }

In your ContentPage add a listview like:

<ListView ItemsSource="{Binding Recommendations}">
 <ListView.ItemTemplate>
   <DataTemplate>
     <ViewCell>
       <Grid Padding="10" RowSpacing="10" ColumnSpacing="10">
         <Grid.RowDefinitions>
           <RowDefinition Height="" />
         </Grid.RowDefinitions>
         <Grid.ColumnDefinitions>
           <ColumnDefinition Width="Auto" />
           <ColumnDefinition Width="" />
           <ColumnDefinition Width="Auto" />
         </Grid.ColumnDefinitions>
         <controls:CircleImage Grid.Column="0" BorderColor="#DDD3CB" 
                               BorderThickness="3" WidthRequest="66"
                               HorizontalOptions="CenterAndExpand" 
                               VerticalOptions="CenterAndExpand" 
                               Aspect="AspectFill" 
                               Source="{Binding Image}" />
         <Label Grid.Column="1" Text="{Binding Description}" 
                               VerticalOptions="Start" />
         <Label Grid.Column="2" Text="{Binding Price, StringFormat='£{0}'"
                               FontSize="Small" VerticalOptions="Start" />
        </Grid>
      </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
 </ListView>

Then in your ContentPage code:

  RoomViewModel vm = null;
  public RoomPage ()
  {
      InitializeComponent ();
      LoadData();
  }

  public void LoadData()
  {
      if (vm == null)
      {
          vm = new RoomViewModel();
          BindingContext = vm;
      }
  }

Happy coding!

Xamarin Forms MasterDetail Page Navigation Recipe

In this recipe I will show you how to add a hamburger menu to your Xamarin Forms application using the MasterDetailPage class. The Xamarin.Forms MasterDetail Page consists of one page for the master and one or more pages for the detail.

When used for the main navigation, as in this recipe, we will have a single master page and 4 detail pages. The code for this recipe comes from the Xamarin Forms CRM sample. I have simplified and streamlined the code, and a full Xamarin Studio solution is included at the bottom of this post.

Xamarin.Forms MasterDetail

Think of the MasterDetailPage as the traffic cop of your application navigation. When a user clicks on the hamburger menu, Xamarin.Forms MasterDetail pushes the menu onto the screen. Then when the user taps on a menu item, MasterDetail creates the target page and pushes it onto the stack. Besides those two things, and some styling, MasterDetail doesn’t do much. Have a look at the code.

public class RootPage : MasterDetailPage
{
	public RootPage ()
	{
		var menuPage = new MenuPage ();
		menuPage.Menu.ItemSelected += (sender, e) => 
                             NavigateTo (e.SelectedItem as MenuItem);
		Master = menuPage;
		Detail = new NavigationPage (new ContractsPage ());
	}

	void NavigateTo (MenuItem menu)
	{
		Page displayPage = (Page)Activator.CreateInstance (menu.TargetType);
		Detail = new NavigationPage (displayPage);
		IsPresented = false;
	}
}

Pretty simple right? The only complicated bit is with the (Page)Activator.CreateInstance (menu.TargetType) part, but if you have been doing C# on .Net for a while, you probably have seen it before. All it is, is another way of creating objects.

MasterBehavior

In Xamarin.Forms 1.3, the Xamarin.Forms MasterDetail MasterDetail Page received a new property called MasterBehavior. This property controls how the menu will react when activated. The enumeration MasterBehavior has a few options and they are:

public enum MasterBehavior
{
    Default,
    Popover,
    Split,
    SplitOnLandscape,
    SplitOnPortrait
}

The normal behavior of the MasterDetailPage in landscape mode is “SplitOnLandscape”. I think splitting is normal when using the MasterDetailPage for detail drill in type navigation but not when using it as a hamburger menu or your apps main navigation. When using the MasterDetailPage for app navigation, I set the behavior to popover.

The Menu Page

The menu page is just what the name implies, it’s the Xamarin Forms page that will be shown when the user clicks the menu button. This is the master part of the Xamarin.Forms MasterDetail Page. Our MenuPage is a simple content page with a StackLayout containing a label and a ListView of our menu items.

Please note the public property Menu. This property allows our MasterDetail page access to the ItemSelected event. When the event is fired, the item selected will be sent to the NavigateTo method on the master detail object.

public class MenuPage : ContentPage
{
	public ListView Menu { get; set; }

	public MenuPage ()
	{
		Icon = "settings.png";
		Title = "menu"; // The Title property must be set.
		BackgroundColor = Color.FromHex ("333333");

		Menu = new MenuListView ();

		var menuLabel = new ContentView {
			Padding = new Thickness (10, 36, 0, 5),
			Content = new Label {
				TextColor = Color.FromHex ("AAAAAA"),
				Text = "MENU", 
			}
		};

		var layout = new StackLayout { 
			Spacing = 0, 
			VerticalOptions = LayoutOptions.FillAndExpand
		};
		layout.Children.Add (menuLabel);
		layout.Children.Add (Menu);

		Content = layout;
	}
}

Menu Item

Menu Item is a simple type that holds our menu data and the most important data is the Target type. When a user clicks on a menu item, the NavigateTo method will create a new page from the TargetType, and push that page onto the stack.

public class MenuItem
{
	public string Title { get; set; }
	public string IconSource { get; set; }
	public Type TargetType { get; set; }
}

Menu List View

The menu list view couldn’t be simpler; we use the built in ImageCell for the rows and set the bindings to the properties on the MenuItem type. We set the first item as the selected item and also used it when constructing the MasterDetail Page initial detail class.

public class MenuListView : ListView
{
	public MenuListView ()
	{
		List data = new MenuListData ();

		ItemsSource = data;
		VerticalOptions = LayoutOptions.FillAndExpand;
		BackgroundColor = Color.Transparent;

		var cell = new DataTemplate (typeof(ImageCell));
		cell.SetBinding (TextCell.TextProperty, "Title");
		cell.SetBinding (ImageCell.ImageSourceProperty, "IconSource");

		ItemTemplate = cell;
	}
}

Menu List Data

The MenuListData class is a data structure holding our applications navigation. In your app you could get this data from the database or configuration file. The menu structure of my application doesn’t change much, so I just use code.

public class MenuListData : List
{
	public MenuListData ()
	{
		this.Add (new MenuItem () { 
			Title = "Contracts", 
			IconSource = "contracts.png", 
			TargetType = typeof(ContractsPage)
		});

		this.Add (new MenuItem () { 
			Title = "Leads", 
			IconSource = "Lead.png", 
			TargetType = typeof(LeadsPage)
		});

		this.Add (new MenuItem () { 
			Title = "Accounts", 
			IconSource = "Accounts.png", 
			TargetType = typeof(AccountsPage)
		});

		this.Add (new MenuItem () {
			Title = "Opportunities",
			IconSource = "Opportunity.png",
			TargetType = typeof(OpportunitiesPage)
		});
	}
}

The Content Pages

These pages are what is created when a user clicks on our menu items.

public class ContractsPage : ContentPage
{
	public ContractsPage (){}
}

public class LeadsPage : ContentPage
{
	public LeadsPage (){}
}

public class AccountsPage : ContentPage
{
	public AccountsPage (){}
}

public class OpportunitiesPage : ContentPage
{
	public OpportunitiesPage (){}
}

Download the source code PSC-MasterDetail.zip (79.74 kb)

Happy coding!

Remove multiple line in the same file with C#

Read the file, remove the multiple line (but it saves one of them) in memory and put the contents back to the file (overwriting) and create a backup file with the original file.

 

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace DelMultiLine {
   class Program {
      static void Main(string[] args) {
         if (args.Count() == 0 || args.Count() > 2) {
            Console.WriteLine("\nDelMultiLine (by Enrico Rossini - puresourcecode.com)");
            Console.WriteLine("-----------------------------------------------------------------------");
            Console.WriteLine("Remove duplicate line in a file\n");
            Console.WriteLine("Usage:");
            Console.WriteLine("   delmultiline <Filename> <resultFilename>\n");
            Console.WriteLine("filename:       define a full path for the file you want to elaborate");
            Console.WriteLine("resultFilename: define the full path for the original file for a backup");
            Environment.Exit(0);
         }

         string file1 = args[0];
         string file2 = "";

         if (args.Count() == 1) {
            if (string.IsNullOrEmpty(file2)) {
               file2 = file1 + ".old";
            }
            else {
               file2 = args[1];
            }
         }

         Console.WriteLine(string.Format("Reading {0} in progress...", args[0]));
         string[] lines = File.ReadAllLines(file1);
         List<string> newline = new List<string>();

         for (int i = 0; i < lines.Length; i++) {
            newline.Add(lines[i]);
         }

         Console.WriteLine("Deleting multiple line in progress...");
         for (int i = 0; i < lines.Length; i++) {
            List<string> temp = new List<string>();
            int duplicate_count = 0;

            for (int j = newline.Count - 1; j >= 0; j--) {
               //checking for duplicate records
               if (lines[i] != newline[j])
                  temp.Add(newline[j]);
               else {
                  duplicate_count++;
                  if (duplicate_count == 1)
                     temp.Add(lines[i]);
               }
            }
            newline = temp;
         }

         // reverse the array
         newline.Reverse();

         //assigning into a string array
         string[] newFile = newline.ToArray();
         newline.Sort();

         // move the original file in a new location
         Console.WriteLine(string.Format("Copying original file in {0}", args[0]));
         File.Move(file1, file2);

         //now writing the data to a text file
         Console.WriteLine(string.Format("Write new file {0}", args[0]));
         File.WriteAllLines(file1, newFile);

         Console.WriteLine("Convertion is finished.");
         Console.WriteLine("\nPress any key to continue...");
         Console.ReadLine();
      }
   }
}

Happy coding!

Dijkstra's Algorithm in C# with Generics

I recently needed to to implement a shortest-path algorithm (to identify preferred domain controllers using site link costs) and I found Dijkstra's Algorithm

Path class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DijkstraAlgorithm {
   public class Path<T> {
      public T Source { get; set; }

      public T Destination { get; set; }

      /// <summary>
      /// Cost of using this path from Source to Destination
      /// </summary>
      /// 
      /// Lower costs are preferable to higher costs
      /// </remarks>
      public int Cost { get; set; }
   }
}

ExtensionMethods class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DijkstraAlgorithm {
   public static class ExtensionMethods {
      /// <summary>
      /// Adds or Updates the dictionary to include the destination and its associated cost 
      /// and complete path (and param arrays make paths easier to work with)
      /// </summary>
      public static void Set<T>(this Dictionary<T, KeyValuePair<int, LinkedList<Path<T>>>> Dictionary, 
                                T destination, int Cost, params Path<T>[] paths) {
         var CompletePath = paths == null ? new LinkedList<Path<T>>() : new LinkedList<Path<T>>(paths);
         Dictionary[destination] = new KeyValuePair<int, LinkedList<Path<T>>>(Cost, CompletePath);
      }
   }
}

Engine class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DijkstraAlgorithm {
   /// <summary>
   /// Calculates the best route between various paths, using Dijkstra's algorithm
   /// </summary>
   public static class Engine {
      public static LinkedList<Path<T>> CalculateShortestPathBetween<T>(T source, T destination, IEnumerable<Path<T>> Paths) {
         return CalculateFrom(source, Paths)[destination];
      }

      public static Dictionary<T, LinkedList<Path<T>>> CalculateShortestFrom<T>(T source, IEnumerable<Path<T>> Paths) {
         return CalculateFrom(source, Paths);
      }

      private static Dictionary<T, LinkedList<Path<T>>> CalculateFrom<T>(T source, IEnumerable<Path<T>> Paths) {
         // validate the paths
         if (Paths.Any(p => p.Source.Equals(p.Destination)))
            throw new ArgumentException("No path can have the same source and destination");

         // keep track of the shortest paths identified thus far
         Dictionary<T, KeyValuePair<int, LinkedList<Path<T>>>> ShortestPaths = new Dictionary<T, KeyValuePair<int, LinkedList<Path<T>>>>();

         // keep track of the locations which have been completely processed
         List<T> LocationsProcessed = new List<T>();

         // include all possible steps, with Int.MaxValue cost
         Paths.SelectMany(p => new T[] { p.Source, p.Destination })           // union source and destinations
                 .Distinct()                                                  // remove duplicates
                 .ToList()                                                    // ToList exposes ForEach
                 .ForEach(s => ShortestPaths.Set(s, Int32.MaxValue, null));   // add to ShortestPaths with MaxValue cost

         // update cost for self-to-self as 0; no path
         ShortestPaths.Set(source, 0, null);

         // keep this cached
         var LocationCount = ShortestPaths.Keys.Count;

         while (LocationsProcessed.Count < LocationCount) {
            T _locationToProcess = default(T);

            //Search for the nearest location that isn't handled
            foreach (T _location in ShortestPaths.OrderBy(p => p.Value.Key).Select(p => p.Key).ToList()) {
               if (!LocationsProcessed.Contains(_location)) {
                  if (ShortestPaths[_location].Key == Int32.MaxValue)
                     return ShortestPaths.ToDictionary(k => k.Key, v => v.Value.Value); //ShortestPaths[destination].Value;

                  _locationToProcess = _location;
                  break;
               }
            } // foreach

            var _selectedPaths = Paths.Where(p => p.Source.Equals(_locationToProcess));

            foreach (Path<T> path in _selectedPaths) {
               if (ShortestPaths[path.Destination].Key > path.Cost + ShortestPaths[path.Source].Key) {
                  ShortestPaths.Set(
                      path.Destination,
                      path.Cost + ShortestPaths[path.Source].Key,
                      ShortestPaths[path.Source].Value.Union(new Path<T>[] { path }).ToArray());
               }
            }

            //Add the location to the list of processed locations
            LocationsProcessed.Add(_locationToProcess);
         } // while

         return ShortestPaths.ToDictionary(k => k.Key, v => v.Value.Value);
         //return ShortestPaths[destination].Value;
      }
   }
}

Test

using System.Linq;
using DijkstraAlgorithm;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTestProject1 {
   [TestClass]
   public class UnitTest1 {
      [TestMethod]
      public void Calculate_A_to_D_given_AB_BC_CD__should_be__ABCD() {
         var Results = Engine.CalculateShortestPathBetween(
             "A",
             "D",
             new Path<string>[] {
                new Path<string>() { Source = "A", Destination = "B", Cost = 3 },
                new Path<string>() { Source = "B", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "C", Destination = "D", Cost = 3 }
             });

         Results.Sum(r => r.Cost).Should().Be(9);
         Results.Count.Should().Be(3);

         Results.First().Cost.Should().Be(3);
         Results.First().Source.Should().Be("A");
         Results.First().Destination.Should().Be("B");

         Results.Skip(1).First().Cost.Should().Be(3);
         Results.Skip(1).First().Source.Should().Be("B");
         Results.Skip(1).First().Destination.Should().Be("C");

         Results.Skip(2).First().Cost.Should().Be(3);
         Results.Skip(2).First().Source.Should().Be("C");
         Results.Skip(2).First().Destination.Should().Be("D");
      }

      [TestMethod]
      public void Calculate_A_to_D_given_AB_BC_CD_DE__should_be__ABCD() {
         var Results = Engine.CalculateShortestPathBetween(
             "A",
             "D",
             new Path<string>[] {
                new Path<string>() { Source = "A", Destination = "B", Cost = 3 },
                new Path<string>() { Source = "B", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "C", Destination = "D", Cost = 3 },
                new Path<string>() { Source = "D", Destination = "E", Cost = 3 }
             });

         Results.Sum(r => r.Cost).Should().Be(9);
         Results.Count.Should().Be(3);

         Results.First().Cost.Should().Be(3);
         Results.First().Source.Should().Be("A");
         Results.First().Destination.Should().Be("B");

         Results.Skip(1).First().Cost.Should().Be(3);
         Results.Skip(1).First().Source.Should().Be("B");
         Results.Skip(1).First().Destination.Should().Be("C");

         Results.Skip(2).First().Cost.Should().Be(3);
         Results.Skip(2).First().Source.Should().Be("C");
         Results.Skip(2).First().Destination.Should().Be("D");
      }

      [TestMethod]
      public void Calculate_A_to_D_given_AB_AC_AD_AE_BC_CD_DE__should_be__ACD() {
         var Results = Engine.CalculateShortestPathBetween(
             "A",
             "D",
             new Path<string>[] {
                new Path<string>() { Source = "A", Destination = "B", Cost = 3 },
                new Path<string>() { Source = "A", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "A", Destination = "D", Cost = 7 }, // set this just above ABC (3+3=6)
                new Path<string>() { Source = "A", Destination = "E", Cost = 3 },
                new Path<string>() { Source = "B", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "C", Destination = "D", Cost = 3 },
                new Path<string>() { Source = "D", Destination = "E", Cost = 3 }
             });

         Results.Sum(r => r.Cost).Should().Be(6);
         Results.Count.Should().Be(2);

         Results.First().Cost.Should().Be(3);
         Results.First().Source.Should().Be("A");
         Results.First().Destination.Should().Be("C");

         Results.Skip(1).First().Cost.Should().Be(3);
         Results.Skip(1).First().Source.Should().Be("C");
         Results.Skip(1).First().Destination.Should().Be("D");
      }

      [TestMethod]
      public void Calculate_A_to_D_given_AB_AC_AD_AE_BC_CD_DE__should_be__AD() {
         var Results = Engine.CalculateShortestPathBetween(
             "A",
             "D",
             new Path<string>[] {
                new Path<string>() { Source = "A", Destination = "B", Cost = 3 },
                new Path<string>() { Source = "A", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "A", Destination = "D", Cost = 5 }, // set this just below ABC (3+3=6)
                new Path<string>() { Source = "A", Destination = "E", Cost = 3 },
                new Path<string>() { Source = "B", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "C", Destination = "D", Cost = 3 },
                new Path<string>() { Source = "D", Destination = "E", Cost = 3 }
             });

         Results.Sum(r => r.Cost).Should().Be(5);
         Results.Count.Should().Be(1);

         Results.Single().Cost.Should().Be(5);
         Results.Single().Source.Should().Be("A");
         Results.Single().Destination.Should().Be("D");
      }
   }
}

You can find the code on GitHub.

Happy coding!

Advertsing

125X125_06

Planet Xamarin

Planet Xamarin

Calendar

<<  July 2017  >>
MonTueWedThuFriSatSun
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar

Month List