Monday, April 12, 2021

Simple .NET5 C# example to show a Message box using AvaloniaUI

The cross platform AvaloniaUI (https://avaloniaui.net/) does not come with a message box class. In order to display message boxes like typical Windows applications, you have to use third party libraries. One such tool is the MessageBox.Avalonia NuGet package (https://github.com/AvaloniaUtils/MessageBox.Avalonia). 

This post shows how to create a simple Hello World project that calls the message box package to open up a modal message box from a main window. 

Create an AvaloniaUI MVVM project

  1. In a Terminal, type in the command to create a project:

    $ dotnet new avalonia.mvvm -o hellomsg

    The template "Avalonia .NET Core MVVM App" was created successfully.

  2. In the Terminal, change directory into the newly created project. Then install the MessageBox.Avalonia Nuget package.

    $ cd /path/to/hellomsg
    $ dotnet add package MessageBox.Avalonia


      Determining projects to restore...                                            
      Writing /tmp/tmpaumBpn.tmp                                                    
    info : Adding PackageReference for package 'MessageBox.Avalonia' into project '/path/to/hellomsg/hellomsg.csproj'
    .    
    ...etc..

     

Add a button to the newly created XAML file

  1. Using a text editor, open up the MainWindow.axaml file.

  2. Remove the TextBlock and add in a Button, as shown below.

    <Window xmlns="https://github.com/avaloniaui"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:vm="using:hellomsg.ViewModels"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
            x:Class="hellomsg.Views.MainWindow"
            Icon="/Assets/avalonia-logo.ico"
            Title="hellomsg">
    
        <Design.DataContext>
            <vm:MainWindowViewModel/>
        </Design.DataContext>
    
        <!-- <TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/> -->
        <Button
            Command="{Binding ShowMsgBoxCommand}"
            CommandParameter="{Binding $parent[Window]}"
            Content="Open MessageBox"
        />
    
    </Window>
    

    Note 1: The Button's Command will bind to a ShowMsgBoxCommand in the MainWindowViewModel.
    Note 2: The Button will pass in the Window object to the ShowMsgBoxCommand through the CommandParameter
    .

Create the ShowMsgBoxCommand in the View Model

  1. In a text editor, open up the file MainWindowViewModel.cs.

  2. Add in a new ReactiveCommand property and name it as ShowMsgBoxCommand.


    public ReactiveCommand<object, Unit> ShowMsgBoxCommand { get; }
    


    Note: this command will take in an object and return the default Unit.

  3. In the constructor, add in the code to create the ShowMsgBoxCommand command. Inside the command, create the message box, define the parameters and display it.

    ShowMsgBoxCommand = ReactiveCommand.CreateFromTask<object>( async (sender) => {
    var dialog = MessageBoxManager
                    .GetMessageBoxStandardWindow("My title", "My message");
    await dialog.ShowDialog(sender as Avalonia.Controls.Window);
    });
    


    Note: pass in the Window object as the owner of the message box to the ShowDialog method.

  4. The full listing of MainWindowViewModel.cs is shown below.


    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Reactive;
    using ReactiveUI;
    using MessageBox.Avalonia;
    
    namespace hellomsg.ViewModels
    {
        public class MainWindowViewModel : ViewModelBase
        {
            public ReactiveCommand<object, Unit> ShowMsgBoxCommand { get; }
            public string Greeting => "Welcome to Avalonia!";
            public MainWindowViewModel(){
                ShowMsgBoxCommand = ReactiveCommand.CreateFromTask<object>( async (sender) => {
                    var dialog = MessageBoxManager
                                    .GetMessageBoxStandardWindow("My title", "My message");
                    await dialog.ShowDialog(sender as Avalonia.Controls.Window);
                });
            }
        }
    }
    

Run the application

  1. In the Terminal, run the dotnet application.

    $ dotnet run

  2. If all is correct, the following should appear. When the button is clicked, a modal message box should pop up.



Monday, April 5, 2021

How to resolve: Unable to load shared library 'libSkiaSharp' when trying to run an AvaloniaUI .NET 5 app

I was trying to run a simple .NET 5 application that uses the cross platform AvaloniaUI graphical user interface library on Ubuntu 20.04. More information about AvaloniaUI can be found on https://avaloniaui.net/. But after executing the command $ dotnet run, the exception error messages appear complaining about a missing libSkiaSharp shared object file, as shown in the screenshot below.

 

After some investigations, I managed to resolve the problem by removing the dotnet SDK binaries that come from the Ubuntu's Snap PPA repositories, that are installed when the following command is executed:


Instead of using Ubuntu's repo, the official Microsoft installer from https://dotnet.microsoft.com/download/dotnet/5.0 should be used instead. 

After installing the official SDK, running the application brings up the application's graphical user interface without any error messages, as shown below.