Jump directly to content
English Deutsch

CSharp and Xamarin tips

This is a small collection of code samples, I wrote for my personal use. Later I decided to make it public, like my other pages for Delphi and PHP code. The functions are all free and tested and most of them are written by myself.

If you found something useful, I'm happy to hear about it. Also suggestions to the functions are very welcome, don't hesitate to send me an email to .

Overview


CSharp tips

Obj und nuget Dateien ausserhalb des Projektverzeichnisses plazieren.

Jedes CSharp Projekt besitzt ein obj Unterverzeichnis innerhalb des Projektverzeichnisses, in welchem der Compiler seine Zwischenergebnisse ablegt. Manchmal ist das ein bisschen unpraktisch, besonders beim Arbeiten mit Backups und Versionsverwaltungssystemen. Wir können das Projekt aber so einrichten, dass es das obj Verzeichnis ausserhalb des Projektverzeichnisses erstellt, dazu einfach das *.csproj manuell mit folgenden Zeilen ergänzen und MyProject mit dem Namen des eigenen Projekts ersetzen:

MyProject.csproj
...
<PropertyGroup>
  <BaseIntermediateOutputPath>$(TEMP)\MyProject\obj\</BaseIntermediateOutputPath>  
</PropertyGroup>

Die Zeilen sollten vor anderen Properties stehen, so können wir Problemen mit Abhängigkeiten, wie NuGet packages, aus dem Weg gehen.

Um das packages Verzeichnis von NuGet packages zu vermeiden, kann man ein config file ins Verzeichnis der Solution plazieren.

NuGet.Config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="repositoryPath" value="%TEMP%/MyProject.NugetPackages" />
  </config>
</configuration>

Using text resources of Windows

Did you already write a small useful function for your library, but then it became difficult to share it, because you needed to deliver translated text resources? Maybe you can borrow the textes from the Windows environment, at least some of the most common textes. To find out which text resources are available, just open the windows library in VisualStudio and switch to the String-Table node.

using System;
using System.Runtime.InteropServices;
using System.Text;

/// <summary>
/// Searches for a text resource in a Windows library. Sometimes, using the
/// existing Windows resources, you can make your code language independent
/// and you don't have to care about translation problems.
/// </summary>
internal class Sto_WindowsString
{
  /// <summary>
  /// Searches for a text resource in a Windows library.
  /// </summary>
  /// <example>
  ///   btnCancel.Text = Sto_WindowsString.Load("user32.dll", 801, "Cancel");
  ///   btnYes.Text = Sto_WindowsString.Load("user32.dll", 805, "Yes");
  /// </example>
  /// <param name="libraryName">Name of the windows library like "user32.dll"
  /// or "shell32.dll"</param>
  /// <param name="ident">Id of the string resource.</param>
  /// <param name="defaultText">Return this text, if the resource string could
  /// not be found.</param>
  /// <returns>Requested string if the resource was found,
  /// otherwise the <paramref name="defaultText"/></returns>
  public static string Load(string libraryName, uint ident, string defaultText)
  {
    IntPtr libraryHandle = GetModuleHandle(libraryName);
    if (libraryHandle != IntPtr.Zero)
    {
      StringBuilder sb = new StringBuilder(1024);
      int size = LoadString(libraryHandle, ident, sb, 1024);
      if (size > 0)
        return sb.ToString();
    }
    return defaultText;
  }

  [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  private static extern IntPtr GetModuleHandle(string lpModuleName);

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
  private static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
}

Stable and parallel Mergesort

When you call the sort method of a list or of an array, you will finally use the Array.Sort() function, which implements a fast Quicksort. This can be very handy, but especially when you have to sort a list of objects with multiple attributes (like database records), there are some drawbacks. Because of these drawbacks, and because I couldn't find code for a parallel and stable sorting, I implemented a Mergesort, with following advantages over the built-in sort function:

  1. The Mergesort is stable, this means that equal elements will preserve their relative position and won't get mixed up. This allows the user to first sort by one attribute, and afterwards by another attribute.
  2. The implementation is done parallel, so it can take advantage of several available processor cores.
  3. The Mergesort needs much less comparisons. While copying objects is a cheap pointer operation, the comparison of two objects can be quite expensive.

View class: StoParallelMergeSort.cs
Download sourcecode: StoParallelMergeSort.zip


Xamarin tips

Implementing a splash screen in Xamarin

The splash screen is the first contact with your app, it welcomes the user while (s)he has to wait until the app finished starting up. So instead of showing of a white screen, we certainly should take advantage of this (hopefully short) time.

Xamarin.Android

Regardless whether it is a Xamarin.Forms or a native project, the splash screen has to be done in the platform dependend project. First we have to create a new drawable Xml and maybe a good quality picture.

MyProject.Android/Resources/drawable/myproject_splash_picture.png
MyProject.Android/Resources/drawable/myproject_splash_screen.xml

<?xml version="1.0" encoding="utf-8" ?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <color android:color="#387aa8"/>
    </item>
    <item>
        <bitmap
            android:src="@drawable/myproject_splash_picture"
            android:gravity="center"/>
    </item>
</layer-list>

In a second step we add a new style for the main activity.

MyProject.Android/Resources/values/styles.xml

<?xml version="1.0" encoding="utf-8" ?>
<resources>
    <style name="MainTheme" parent="MainTheme.Base">
    </style>

    <style name="MainTheme.MySplashScreen" parent="MainTheme">
        <item name="android:windowBackground">@drawable/myproject_splash_screen</item>
    </style>  

As a last step we tell the main activity to use this style, declaring it in the Activity attribute. As soon as the app reaches the OnCreate method, we switch back to the real background theme.

MyProject.Android/MainActivity.cs

[Activity(Label = "MyProject", Theme = "@style/MainTheme.MySplashScreen", MainLauncher = true, ...]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        // Clear the splash screen theme declared as attribute of the activity.
        SetTheme(Resource.Style.MainTheme);  

Xamarin.UWP

For UWP projects, just open the MyProject.UWP/Package.appxmanifest and navigate to Visual Assets/Splash Screen. There you can add an image and define a background color.


Using razor pages in Xamarin.Forms

Xamarin offers the Razor template engine, which allows to write HTML pages at design time, and let Xamarin populate it at runtime with data from a ViewModel. This is very convenient, but is not (yet) offered for all types of projects, usually only for hybrid web apps. That doesn't mean that it cannot be used for other types of projects like Xamarin.Forms.

❶ If no razor template can be found in the add/new item..., just add a new empty class (or whatever you like) to the project. Then rename the file to *.cshtml and replace the content with a skeleton like this:

MyProject/Views/MyRazorView.cshtml

@using MyProject.ViewModels
@model MyRazorViewModel
<html>
<body>
  <h1>@Model.Title</h1>
</body>
</html>
Razor template properties

❷ Then go to the class properties, find the CustomTool property and type in RazorTemplatePreprocessor. VisualStudio now magically creates the belonging MyRazorView.cs file with the code-behind.

❸ Finally we can build the HTML page whenever we need it.

MyProject/MainActivity.cs

var viewModel = new MyRazorViewModel(...);
var razorTemplate = new MyRazorView { Model = viewModel };
string html = razorTemplate.GenerateString();