A cross-platform project template for Windows and Linux, using the MVVM design pattern for easier maintenance and testing.
- Introduction
- Features
- Getting Started
- Publishing
- How to Add a New Content Control]
- How to Show a Message Box]
- Debugging
- Contributing
- License
rpiApp is a project template designed to facilitate the development of cross-platform applications for both Windows and Linux. It leverages the Model-View-ViewModel (MVVM) design pattern to ensure that the codebase is maintainable and testable.
- Avalonia GUI Framework
- Cross-platform support for Windows and Linux
- MVVM design pattern
- Semantic versioning for version management
- Examples using the following NuGet Packages
- Serilog logging
- IoT Device Bindings for various IoT boards, chips, displays and PCBs including RPi.
- Property Grid for easy editing of a class properties.
- MVVM DialogsLibrary simplifying the concept of opening dialogs and message boxes from a view model when using MVVM
- LiveChart2 Simple, flexible, interactive & powerful charts, maps and gauges for .Net
- Microsoft Extensions Dependency Injection Supports the dependency injection (DI) software design pattern which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies.
- Avalonia Edit Text editor with syntax highlighting, code completion, and tons of other features.
- .NET 9 SDK
- Visual Studio 2022 or any other compatible IDE
Select from GitHub (https://github.com/mrhodel/rpiApp.git) to create a new repository
To publish the application, you can use Visual Studio:
- Open the project in Visual Studio.
- Right-click the project in Solution Explorer and select Publish.
- Select a publish profile
(Select linux-arm64 for Raspberry Pi)
- Click Publish.
The published files will be available in the specified folder. You can then distribute these files as needed. Note: For debugging on Linux do not check "Produce Single File" found in File Publish Options.
/*
* YOURViewModel.cs
* 1/26/2025 YOU
*/
namespace YOURApp.ViewModels;
public class YOURViewModel : ViewModelBase
{
}
<!--
YOURView.axaml
1/26/2025 YOU
-->
<UserControl
x:Class="YOURAPP.Views.YOURView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:YOURApp.ViewModels"
d:DesignHeight="450"
d:DesignWidth="800"
x:DataType="vm:YOURViewModel"
mc:Ignorable="d">
<Design.DataContext>
<!--
this only sets the datacontext for the previewer in an ide,
to set the actual datacontext for runtime, set the datacontext property in code (look at app.axaml.cs)
-->
<vm:YOURViewModel />
</Design.DataContext>
<grid/>
</UserControl>
Inherit UserControl from your code behind file. Note: This file is created automatically when you add a control to your project.
using Avalonia.Controls;
namespace YOURApp.Views;
public partial class YOURView : UserControl
{
public YOURView()
{
InitializeComponent();
}
}
.AddTransient<YOURViewModel>()
If you want to show your Content Control as a dialog, add an extension method to DialogExtensions.cs
public static async Task<bool?> ShowYOURViewAsync(this IDialogService dialog, INotifyPropertyChanged? ownerViewModel)
{
var viewModel = dialog.CreateViewModel<YOURViewModel>();
var settings = new DialogHostSettings(viewModel)
{
DialogMargin = new Avalonia.Thickness(20),
DisableOpeningAnimation = false,
CloseOnClickAway = true
};
// If the calling view model is for a window then use that window as the owner, otherwise use the main view.
Guard.IsNotNull(_mainView);
await dialog.ShowDialogHostAsync((ownerViewModel is not null) ? ownerViewModel : _mainView, settings);
return viewModel.DialogResult;
}
var result = await _dialogService.ShowCameraInfoViewAsync(null);
Debug.WriteLine($"Dialog result: {result}");
var result = await _dialogService!.ShowMessageBoxAsync(
null,
"Not implemented", "",
MessageBoxButton.Ok,
MessageBoxImage.Warning,
null);
Debug.WriteLine($"Dialog result: {result}");
- Copy the published files to the target system. I recommend WinSCP to sync your local publish folder with the remote device.
- Run the application on the remote device.
- Select Attach to Process... from the Visual Studio Debug menu.
- Enter the Connection type and connection target.
- Select the application from the list, and click connect.
Contributions are welcome! Please fork the repository and submit a pull request with your changes. Ensure that your code adheres to the existing coding style and includes appropriate tests.
This project is licensed under the MIT License. See the LICENSE file for more details.