ExtWebView

My custom WebView. It has a HTML string property. This was very useful to draw my chart :) a simple HTML file with some embedded Javascript to draw the shapes. It was the faster way for me to make a cross pie chart control. When the HTML property has changed, the source of the WebView gets updated.

//
// <copyright file=ExtWebView.cs company=Krossapp>
//     Copyright (c) Krossapp. All rights reserved.
// </copyright>
// <author>Nicolas Krier</author>
//
namespace SDF.XForm.Controls
{
    #region Using

    using System.Diagnostics.CodeAnalysis;
    using System.Windows.Input;
    using Xamarin.Forms;

    #endregion

    /// <summary>
    /// Web view.
    /// </summary>
    public class ExtWebView : WebView
    {
        #region Bindable property

        /// <summary>
        /// The html property.
        /// </summary>
        [SuppressMessage(StyleCop.CSharp.MaintainabilityRules, SA1401:FieldsMustBePrivate, Justification = Reviewed.)]
        public static BindableProperty HtmlProperty = BindableProperty.Create<ExtWebView, string>(x => x.Html, null, BindingMode.OneWay, propertyChanged: WhenHtmlChanged);

        /// <summary>
        /// The command clicked property.
        /// </summary>
        [SuppressMessage(StyleCop.CSharp.MaintainabilityRules, SA1401:FieldsMustBePrivate, Justification = Reviewed.)]
        public static BindableProperty Command = BindableProperty.Create<ExtWebView, ICommand>(x => x.CommandClicked, null);

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref=ExtWebView/> class.
        /// </summary>
        public ExtWebView()
            : base()
        {
            this.HandleTapEvent();
        }

        #endregion

        #region Property

        /// <summary>
        /// Gets or sets the html.
        /// </summary>
        /// <value>The html.</value>
        public string Html
        {
            get { return (string)this.GetValue(HtmlProperty); }
            set { this.SetValue(HtmlProperty, value); }
        }

        /// <summary>
        /// Gets or sets the command clicked.
        /// </summary>
        /// <value>The command clicked.</value>
        public ICommand CommandClicked
        {
            get { return (ICommand)this.GetValue(Command); }
            set { this.SetValue(Command, value); }
        }

        #endregion

        /// <summary>
        /// Raises the html changed event.
        /// </summary>
        /// <param name=sender>The sender.</param>
        /// <param name=oldValue>Old value.</param>
        /// <param name=newValue>New value.</param>
        private static void WhenHtmlChanged(BindableObject sender, string oldValue, string newValue)
        {
            WebView ctrl = (WebView)sender;
            ctrl.Source = new HtmlWebViewSource() { Html = newValue };
        }

        /// <summary>
        /// Handle the tap event : the click.
        /// </summary>
        private void HandleTapEvent()
        {
            /*
            var tapGestureRecognizer = new TapGestureRecognizer();
            tapGestureRecognizer.Tapped += (sender, args) =>
            {
                if (args != null && this.CommandClicked != null && this.CommandClicked.CanExecute(args))
                {
                    this.CommandClicked.Execute(args);
                }
            };
            this.GestureRecognizers.Add(tapGestureRecognizer);
            */
        }
    }
}


ExtProgressBar

This control needs a custom renderer to use the ProgressColor. A custom renderer gives you the possibility to animate the progress bar on iOS when its progress value changes.

//
// <copyright file=ExtProgressBar.cs company=Krossapp>
//     Copyright (c) Krossapp. All rights reserved.
// </copyright>
// <author>Nicolas Krier</author>
//
namespace SDF.XForm.Controls
{
    #region Using

    using System.Diagnostics.CodeAnalysis;
    using Xamarin.Forms;

    #endregion

    /// <summary>
    /// Progress bar.
    /// </summary>
    public class ExtProgressBar : ProgressBar
    {
        #region Bindable property

        /// <summary>
        /// The progress color property.
        /// </summary>
        [SuppressMessage(StyleCop.CSharp.MaintainabilityRules, SA1401:FieldsMustBePrivate, Justification = Reviewed.)]
        public static BindableProperty ProgressColorProperty = BindableProperty.Create<ExtProgressBar, Color>(x => x.ProgressColor, Color.Blue);

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref=ExtProgressBar/> class.
        /// </summary>
        public ExtProgressBar()
            : base()
        {
        }

        #endregion

        #region Property

        /// <summary>
        /// Gets or sets the color of the progress.
        /// </summary>
        /// <value>The color of the progress.</value>
        public Color ProgressColor
        {
            get { return (Color)this.GetValue(ProgressColorProperty); }
            set { this.SetValue(ProgressColorProperty, value); }
        }

        #endregion
    }
}


Starting a new project : PCL or Shared

Xamarin Team talk about pros and cons better than me. So follow the link below.

http://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/sharing_code_options/

Shared project

> You only plan to target Android, iOS and Windows Phone
> You want to start coding as soon as possible
> You don’t plan to use Xamarin but you want to see how it works from a closer look
> You are familiar with #if directives

It works like if you were adding files as link. Every platform’s project will add the files from the shared project as a link. It means that when you add a file in the shared project, every reliant project will add this file.

PCL project

> You plan to use the project in other projects like an ASP.NET project, a WPF project, a Windows 10 app etc.
> You want to reduce dependencies
> You want to separate concerns

Conclusion

I’ve tried both way. I prefer the Portable approach. I’ve always been a huge fan of Portable Class Library and dependency injection. I felt I was coding the base of my application faster with the Shared project at the beginning. As an exemple, you can log what you want in the shared project because you have access to the Debug class. With PCL project, you don’t. So, you have to create an interface of a LogService and its implementation on each platform (e.g. AndroidLogService, iOsLogService, WinPhoneLogService). It’s the same thing with HTTP request : in the PCL project, you don’t have access to the HttpClient class. Thus, we have to make some extra work that isn’t necessary with the shared project.

If you don’t know PCL and dependency injection yet, you may start with the PCL approach as you will learn new interesting things.