Tag Archive : UWP

/ UWP

How to add a Checkbox in Xamarin.Forms

May 14, 2019 | Tutorial | No Comments

We are going to show step by step how to create a Checkbox for Xamarin.Forms with a very simple code without the use of Custom Renderers.This checkbox will work on every platform: Android, iOS, UWP… and the final result will be something like:

Checkbox disabled
Checkbox disabled
Checkbox enabled
Checkbox enabled

There are just two steps you need to do:

  • Add your images
  • Create the Checkbox class

After the two steps, I’m going to show you a small example on how to use this checkbox.

Add the Checkbox images

The first thing to do is to choose two images for the checkbox, one enabled and the other disabled (similat to the ones you can see in the previous images).

Add the images as embedded resources
Add the images as embedded resources

Create an Images folder inside your PCL/.NetStandard project and add the two images in it. Be sure to set the two images as Embedded Resources (as in the previous image).

Add the Checkbox class

Now it’s time to create our checkbox class. Inside your PCL/.NetStandard project create the file Checkbox:

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

namespace Tutorial02
{
    public class Checkbox : StackLayout
    {
        public event EventHandler CheckedChanged;
        private readonly Image _image;

        private readonly Label _label;
        //CHANGE THESE 2 STRINGS ACCORDING TO YOUR NAMESPACE AND IMAGE

        static string imgUnchecked = "Tutorial02.Images.unchecked.png";
        static string imgChecked = "Tutorial02.Images.checked.png";
        public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(Checkbox));

        public static readonly BindableProperty CheckedProperty = BindableProperty.Create("Checked", typeof(Boolean?), typeof(Checkbox), null,
            BindingMode.TwoWay, propertyChanged: CheckedValueChanged);

        public static readonly BindableProperty TextProperty =
            BindableProperty.Create("Text", typeof(String), typeof(Checkbox), null, BindingMode.TwoWay, propertyChanged: TextValueChanged);

        public ICommand Command
        {
            get => (ICommand) GetValue(CommandProperty);
            set => SetValue(CommandProperty, value);
        }

        public Boolean? Checked
        {
            get => (bool?) GetValue(CheckedProperty);
            set => SetValue(CheckedProperty, value);
        }

        public String Text
        {
            get => (string) GetValue(TextProperty);
            set => SetValue(TextProperty, value);
        }

        public Checkbox()
        {
            Orientation = StackOrientation.Horizontal;
            BackgroundColor = Color.Transparent;
            _image = new Image()
                {Source = ImageSource.FromResource(imgUnchecked), HeightRequest = 35, WidthRequest = 35, VerticalOptions = LayoutOptions.Center};
            var tg = new TapGestureRecognizer();
            tg.Tapped += Tg_Tapped;
            _image.GestureRecognizers.Add(tg);
            Children.Add(_image);
            _label = new Label() {VerticalOptions = LayoutOptions.Center};
            _label.GestureRecognizers.Add(tg);
            Children.Add(_label);
        }

        private void Tg_Tapped(object sender, EventArgs e)
        {
            Checked = !Checked;
        }

        private static void CheckedValueChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (newValue != null && (Boolean) newValue) ((Checkbox) bindable)._image.Source = ImageSource.FromResource(imgChecked);
            else ((Checkbox) bindable)._image.Source = ImageSource.FromResource(imgUnchecked);
            ((Checkbox) bindable).CheckedChanged?.Invoke(bindable, EventArgs.Empty);
            ((Checkbox) bindable).Command?.Execute(null);
        }

        private static void TextValueChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (newValue != null) ((Checkbox) bindable)._label.Text = newValue.ToString();
        }
    }
}

Your are now ready to use the checkbox in your apps and it will work for every platform supported by Xamarin. GREAT!Now I’ll show you a small example on how to use this checkbox inside your App:

Add the Checkbox to your ContentPage

Inside the our ContentPage we have set the ViewModel and then added the checkbox:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"             
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"             
             xmlns:local="clr-namespace:Tutorial02"
             xmlns:viewModel="clr-namespace:SafePhoto2.ViewModel;assembly=SafePhoto2"
             x:Class="Tutorial02.MainPage">
    <ContentPage.BindingContext>
        <viewModel:MainViewModel />
    </ContentPage.BindingContext>
    <local:Checkbox VerticalOptions="CenterAndExpand"                     
                    HorizontalOptions="CenterAndExpand"                     
                    Checked="{Binding IsChecked}"                     
                    Text="{Binding TextCheckBox}"                     
                    Command="{Binding OnCheckedChanged}">

    </local:Checkbox>
</ContentPage>

The checkbox has two important properties: Checked and Text.

  • Checked is bound to the IsChecked property of the ViewModel and indicates if the checkbox is checked or not
  • Text is bound to the TextCheckBox property of the ViewModel and is the text that appears next to the CheckBox image

In case you want to execute an action after the status of the checkbox is changed, you can use Command  (bound to the OnCheckedChanged inside the ViewModel) otherwise you can remove it from your XAML.

Create the ViewModel

The ViewModel used in our example is very easy and you can change it as you prefer. For this simple example we have just created a basic ViewModel:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms;

namespace Tutorial02
{
    public class MainViewModel : INotifyPropertyChanged
    {
        private bool _isChecked;
        private string _textCheckBox;
        public event PropertyChangedEventHandler PropertyChanged;

        public bool IsChecked
        {
            get => _isChecked;
            set
            {
                _isChecked = value;
                TextCheckBox = _isChecked ? "Is Enabled" : "Is Disabled";
                OnPropertyChanged();
            }
        }

        public string TextCheckBox
        {
            get => _textCheckBox;
            set
            {
                _textCheckBox = value;
                OnPropertyChanged();
            }
        }

        public Command OnCheckedChanged { get; set; }

        public MainViewModel()
        {
            OnCheckedChanged = new Command(OnCheckBoxChanged);
        }

        private void OnCheckBoxChanged()
        {
        }

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

As usual the ViewModel inherits from INotifyPropertyChanged.We have added two properties IsChecked and TextCheckBox and the Command OnCheckedChanged required only if we want to execute an action after the status of the checkbox is changed.When the IsChecked value changes, we set the Checkbox text to Is Enabled or Is Disabled according to its value.

Conclusion

In this tutorial we have seen how to create a Checkbox in Xamarin.Forms.The code is incredibly easy and ready to be used (you can copy and paste the code and it will work).If you have questions or doubts leave here a comment.If you need more info about the MVVM pattern in Xamarin you can check the Microsoft documentation here: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm

Usually a desktop platform has a lot of available resources so many developers tend to avoid to improve the quality of their code.On a mobile platform the resources are quite limited and improving the code could make a huge difference. It can transform a slow and annoying app in a great fast and great one.Today, using the code I’ve written for one of my app Tv Series Time Manager, we are going to see how improving the code can make a huge difference in the loading time of your apps.

LINQ
LINQ

Improve your code – LINQ is your friend

Tv Series time manager allows you to keep track of your preferred tv series.It uses a public API to get information about all the TV Series created. As you can imagine there are thousands and thousands of Tv Series so we need to handle lists of thousands of items.Every time we launch the app, it searches online updated about the Tv Series you are following (new episodes, release dates, and so on). This can be a quite intensive task as the API we need to call returns a JSON file with more than 34000 items.The first time I’ve written the updated method I had this code:

var localTvShows = LocalData.GetAllTvShows(); 
var remoteUpdatedTime = await WsData.GetUpdatedShows(); 
foreach (var info in remoteUpdatedTime) 
{ 
    var show = localTvShows.FirstOrDefault(x => x.id == info.Key); 
    if (show != null && info.Value > show.updated) 
    { 
        updateRequired = true; 
        break; 
    } 
}

            if (UpdateRequired)
            {
                foreach (var info in remoteUpdatedTime)
                {
                    var show = localTvShows.FirstOrDefault(x => x.id == info.Key);
                    if (show != null && info.Value > show.updated)
                    {
                        var remoteserie = await WsData.GetShow(show.id);
                        SqlHelper.SyncSerie(show, remoteserie);
                        var episodeList = await WsData.GetEpisodes(show.id);
                        SqlHelper.SyncEpisodes(show.idLocal, episodeList);
                    }
                }
            }

I load the local Tv Show followed by the user and the remote Tv Series with the corresponding update time.Inside the first foreach I check if I need to update the local Tv Series.In case I have to update a Tv Series, I use a second foreach to update every local TV Series inside the local Sql database. (To add SQLite database to your app, you can read this tutorial)The code worked pretty well but I wasn’t satisfied by the loading time so I started to look for a way to improve the performances and here I discovered once more that LINQ is our friend.

The new code with LINQ

I decided to use LINQ to evaluate if I have to update a tv series, so I’ve written the code replacing the old one with this:

var seriesToUpdate = from remoteTime in remoteUpdatedTime
                join localShow in localTvShows 
                    on remoteTime.Key equals localShow.id
                where remoteTime.Key == localShow.id && remoteTime.Value > localShow.updated
                select localShow;

            if (seriesToUpdate.Any())
            {
                foreach (var show in seriesToUpdate)
                {
                    var remoteserie = await WsData.GetShow(show.id);
                    SqlHelper.SyncSerie(show, remoteserie);
                    var episodeList = await WsData.GetEpisodes(show.id);
                    SqlHelper.SyncEpisodes(show.idLocal, episodeList);
                }
            }

Speed Test

Now it’s time to see if the new code is really better than the first (Obviously it is 🙂 ). To do so, I’ve divided the code in two parts.

  • Evaluate if an update is required (Part A)
  • Update the Tv Series (Part B).

To give you the idea of how much time we can save, I’ve enclosed both the code in a for statement repeating the it for 100 times. These are the result:

Part A

  • OLD CODE:  Elapsed Time: 1077 ms
  • NEW CODE: Elapsed Time:   225 ms

Part B

  • OLD CODE:  Elapsed Time:  590 ms
  • NEW CODE: Elapsed Time:   122 ms

Total

  • OLD CODE:  Elapsed Time:  1667 ms
  • NEW CODE: Elapsed Time:    347 ms

Looking at the time spent by the old and new code we  went from 1667 ms to 347 ms, saving 1320 ms. The difference is HUGE.From the point of view of a user, saving almost 1.5 seconds makes a massive difference, maybe the difference between keeping your app or uninstalling it.

Conclusion

A mobile device has a limited amount of resources and users don’t like to spend time waiting in front of a loading screen. Even the most useful app, if not optimized will be uninstalled by the users. This is why it’s really important to optimize your code.Today we have seen that with a good use LINQ  we can massively reduce the time used by our code.If you like the article, comment and share it!

Xamarin.Forms is fantastic, you write your code once inside your PCL/.NetStandard project and it will run on many different platforms.However sometimes we need to access directly the native platform. To do so, we can use something called DependencyService.DependencyService allows us to use platform-specific functionality from shared code.To use the DependencyService we need:

  • An interface inside our shared code
  • An implementation for each platform
  • A registration

After the DependencyService is ready, then we can call it from our shared code.If we want to add a Sqlite database to our Xamarin.Forms project, because we cannot create it directly in our shared code, we need to use a DependencyService so in this tutorial we are going to see how to use the DependencyService to create and use a Sqlite database in our multi platform app.

TUTORIAL

First of all, let’s create an empty Xamarin.Forms project using a .NetStandard project. For a tutorial on how to create a Xamarin.Forms project, you can read this guide: http://www.xamarinexpert.it/2018/03/03/xamarin-forms-a-guide-for-beginners/

Empty Xamarin Project
Fig.1 Structure of an empty Xamarin.Forms Project

In the first image you can see the structure of a Xamarin.Forms project.As we said, the creation of a DependencyService consists of 3 steps.

First Step – The interface

Now the first step to do, is to create the Interface for our DependencyService.Let’s create and add an interface called ISql to our .NetStandard project:

public interface ISql
{
    SQLiteConnection GetConnection(string dbname = "database.db3");
    SQLiteAsyncConnection GetConnectionAsync(string dbname = "database.db3");
}

This interface exposes two methods:GetConnection: Get a connection for the Sqlite database.GetConnectionAsync: Get an async connection for the Sqlite database.Really easy. Don’t you think?

Second Step – The implementation

Inside this second step, we need to implement the interface in each platform. Let’s start with Android

Android

We need to create in Android a class the implements the ISql interface, let’s call this class SqlImplementation:

public class SqlImplementation : ISql
{
    public SQLiteConnection GetConnection(string dbname = "database.db3")
    {
        var sqliteFilename = dbname;
        string documentsPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        // Documents folder
        var path = Path.Combine(documentsPath, sqliteFilename);
        var conn = new SQLiteConnection(path, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.FullMutex);
        return conn;
    }

    public SQLiteAsyncConnection GetConnectionAsync(string dbname = "database.db3")
    {
        var sqliteFilename = dbname;
        string documentsPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
        var path = Path.Combine(documentsPath, sqliteFilename);
        return new SQLiteAsyncConnection(path);
    }
}

We have basically implemented the two methods of our ISql interface. These two methods return the native connection to an Android Sqlite database.

iOS

Now we need to create the same class inside the native  iOS project:

public class SqlImplementation : ISql
{
    public SQLiteConnection GetConnection(string dbname = "database.db3")
    {
        var sqliteFilename = dbname;
        string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder

        var path = Path.Combine(documentsPath, sqliteFilename);
        var conn = new SQLiteConnection(path, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.FullMutex);
        return conn;
    }

    public SQLiteAsyncConnection GetConnectionAsync(string dbname = "database.db3")
    {
        var sqliteFilename = dbname;
        string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
        var path = Path.Combine(documentsPath, sqliteFilename);
        return new SQLiteAsyncConnection(path);
    }
}

As you can see the code is basically the same but it’s IMPORTANT to add the implementation to each platform you need to use, otherwise you’ll get an error.

UWP

Now it’s time to implement the interface for UWP:

public class SqlImplementation : ISql
{
    public SQLiteConnection GetConnection(string dbname = "database.db3")
    {
        var sqliteFilename = dbname;
        var path = Path.Combine(ApplicationData.Current.LocalFolder.Path, sqliteFilename);
        var conn = new SQLiteConnection(path, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.FullMutex);
        return conn;
    }

    public SQLiteAsyncConnection GetConnectionAsync(string dbname = "database.db3")
    {
        var sqliteFilename = dbname;
        var path = Path.Combine(ApplicationData.Current.LocalFolder.Path, sqliteFilename);
        return new SQLiteAsyncConnection(path);
    }
}

and this concludes the second step.

Third Step – The registration

it’s extremely important to register the DependencyService otherwise it will not work.Don’t worry, this step is incredibly easy, the only thing you need to do is to add this line of code in each SqlImplementation class just before the namespace:

[assembly: Dependency(typeof(SqlImplementation))]

so for example the final code of your Android implementation will be:

[assembly: Dependency(typeof(SqlImplementation))]

namespace YOURNAMESPACE
{
    public class SqlImplementation : ISql
    {
        public SQLiteConnection GetConnection(string dbname = "database.db3")
        {
            var sqliteFilename = dbname;
            string documentsPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
            var path = Path.Combine(documentsPath, sqliteFilename);
            var conn = new SQLiteConnection(path, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.FullMutex);
            return conn;
        }

        public SQLiteAsyncConnection GetConnectionAsync(string dbname = "database.db3")
        {
            var sqliteFilename = dbname;
            string documentsPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
            var path = Path.Combine(documentsPath, sqliteFilename);
            return new SQLiteAsyncConnection(path);
        }
    }
}

REMEMBER to add the assembly line to EACH of your SqlImplementation classes.

HOW TO USE IT

Now the DependencyService is ready, we just need to call use it. If we want to get the SqLite connection we just need to use a single line of code inside our share code:

SQLiteConnection database = DependencyService.Get<ISQLite>().GetConnection();

Now you have your sql connection in you shared code so you can start to use your SqLite database.

Sqlite Plugin

It’s extremely easy to use the DependencyService to add a Sqlite database to your Xamarin.Forms app, but if you want an already made solution, you can use my Sqlite plugin so after you install it, you can directly use your database with a single line of code:

SQLiteConnection conn = MTSql.Current.GetConnection("yourdatabasename.db3");

It cannot be easier than that.You can find a tutorial on how to use the plugin here: http://www.xamarinexpert.it/2018/03/01/sqlite-made-easy/The official page is here: http://www.xamarinexpert.it/plugins/mt-sqlite/You can find the nuget package here: https://www.nuget.org/packages/MarcTron.Sqlite

More

You have doubts about the DependencyService or Sql? You want to know more? Ask me adding a comment below this article.

Have you ever dreamed to create a 3D game? Or maybe an Augmented Reality app? With Xamarin and UrhoSharp it couldn’t be easier.

UPDATE

The new UrhoSharp tutorial (with source code) is available here:https://www.xamarinexpert.it/blog/urhosharp-tutorial-how-to-create-your-first-project-with-xamarin-forms/

UrhoSharp

UrhoSharp is a lightweight Game Engine suitable for using with C# and F# to create games that run on Android, iOS, Mac, Windows and Unix. The game engine is available as a portable class library, allowing your game code to be written once and shared across all platforms. UrhoSharp is powered by Urho3D (http://urho3d.github.io/), a game engine that has been under development for more than a decade.The idea is the same as Xamarin: you write your code once and your app will run on many different platforms. In this case:

  • Android
  • iOS
  • Mac
  • Windows (WPF and UWP so it will run also on Windows phones)
  • Unix

After several months of silence UrhoSharp has come back strongly with a new release (v.1.8.91) tha fixes many bugs and updates this extremely powerful engine.The biggest news are:

  • Updated to Urho3D 1.7
  • ARKit and ARCore components
  • Fixed major Android and iOS crashes
  • Optional DirectX11 backend for Windows
  • UWP 64bit support (and .NET Native toolchain)

The amazing thing is that with UrhoSharp you can create your 2D/3D games and also create amazing Augmented Reality apps thanks to support to ARKit (iOS) and ARCore (Android).

I’m writing a tutorial on how to use UrhoSharp and I’ll publish it here as soon as it ready.

Meanwhile you can find more info on the official Xamarin website: https://developer.xamarin.com/guides/cross-platform/urhosharp/introduction/

For a beginner’s guide on how to create a Xamarin.Forms app you can read this tutorial: http://www.xamarinexpert.it/2018/03/03/xamarin-forms-a-guide-for-beginners/

Xamarin has a long story of problematic releases where new features comes along with numerous bugs.For this reason is possible that you are still using an old version of Xamarin.Forms.But today you will see why you should really upgrade to Xamarin.Forms 2.5

Layout Compression

Sometimes to create the UI we want, we need to add several layouts that are not visible but are needed as container for other components.As you can imagine, all these layouts come with a cost and you can see it especially on older Android devices.Layout compression helps us to solve this problem reducing the number of views to render.Consider this basic example:

<StackLayout Orientation="Horizontal"                  
                 HorizontalOptions="CenterAndExpand"                  
                 VerticalOptions="CenterAndExpand">
        <Button Text="Yes"></Button>
        <Button Text="No"></Button>
    </StackLayout>

We have a StackLayout that contains two buttons, the only reason to have this layout is to add the two buttons at the same height.Even if we don’t see the layout, having it in our Page has a cost.With the Layout Compression we can keep the StackLayout and remove its cost.To enable the compression of the StackLayout we need to add the codeCompressedLayout.IsHeadless="true"so the previous example will be:

<StackLayout Orientation="Horizontal"                  
                 HorizontalOptions="CenterAndExpand"                  
                 VerticalOptions="CenterAndExpand"                 
                 CompressedLayout.IsHeadless="true">
        <Button Text="Yes"></Button>
        <Button Text="No"></Button>
    </StackLayout>

Easy. Isn’t it? You can enable the Layout compression on: StackLayout, AbsoluteLayout, Grid, RelativeLayout.Because the compression removes the renderer for the layout, candidates for the compression are layouts that don’t have:

  • Background color
  • Gestures
  • Transformations
  • etc.

Layout Compression is available on iOS and Android.

Fast Renderers

Ok this is not entirely a new feature (they arrived on Xamarin.Forms 2.4) but it’s definitely a feature you shouldn’t miss.We love Xamarin but we also know that sometimes, especially on Android the performances are not really amazing.Fast Renderers for Android will improve performances on your Xamarin.Forms applications.As this is still an experimental feature, to enable them you need to add this line

Forms.SetFlags("FastRenderers_Experimental");

to your MainActivity class before calling Forms.Init

I’ve personally tested Layout compression and Fast Renderers and I can confirm that there is a performance improvement especially on older Android devices so I really suggest you to use these features in your projects.

Forms Embedding

I have to tell you, I’m not particularly inclined to mix things so I prefer to keep separated Xamarin.Forms and native Xamarin projects.BUT…I can honestly see cases where you already have existing Xamarin.Forms pages and you want to use in other Xamarin iOS, Android or UWP projects.Thanks to the Forms Embedding now you can do it.

Improved macOS Desktop Support

In case you want to add macOS desktop support in your Xamarin.Forms apps 🙂