A comprehensive WPF toolkit library providing MVVM components, command infrastructure, logging utilities, and configuration management for modern Windows desktop applications. Now includes complete sync/async command implementations with automatic state management and exception handling.
$ dotnet add package DotNetTools.WpfkitA comprehensive WPF toolkit library that provides essential components for building modern Windows desktop applications with the MVVM pattern, logging capabilities, and configuration management.
DotNetTools.Wpfkit is a modern .NET library designed to accelerate WPF application development by providing reusable, production-ready components. Built on .NET 10.0, it embraces modern C# features including nullable reference types, implicit usings, and follows best practices for WPF development.
INotifyPropertyChanged with helper methodsdotnet add package DotNetTools.WpfkitOr via Package Manager Console in Visual Studio:
Install-Package DotNetTools.WpfkitOr add directly to your .csproj:
<PackageReference Include="DotNetTools.Wpfkit" Version="1.0.0" />git clone https://github.com/omostan/DotNetTools.Wpfkit
cd DotNetTools.Wpfkit
dotnet buildBase class for implementing property change notifications:
using DotNetTools.Wpfkit.MvvM;
public class MyModel : ObservableObject
{
private string _name;
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
private int _age;
public int Age
{
get => _age;
set => SetProperty(ref _age, value, onChanged: () => {
// Execute when age changes
OnPropertyChanged(nameof(IsAdult));
});
}
public bool IsAdult => Age >= 18;
}Rich view model base class with common UI properties:
using DotNetTools.Wpfkit.MvvM;
public class MainViewModel : BaseViewModel
{
public MainViewModel()
{
Title = "My Application";
Subtitle = "Welcome Screen";
Icon = "icon.png";
}
public async Task LoadDataAsync()
{
IsBusy = true;
try
{
// Load data
}
finally
{
IsBusy = false;
}
}
}Available Properties:
Title: Main title textSubtitle: Secondary descriptive textIcon: Icon path or resourceIsBusy: Indicates loading stateIsNotBusy: Inverse of IsBusyCanLoadMore: Pagination supportHeader: Header contentFooter: Footer contentEnhanced collection with bulk operations:
using DotNetTools.Wpfkit.MvvM;
var collection = new ObservableRangeCollection<string>();
// Add multiple items efficiently
var items = new[] { "Item1", "Item2", "Item3" };
collection.AddRange(items);
// Replace entire collection
collection.ReplaceRange(newItems);
// Remove multiple items
collection.RemoveRange(itemsToRemove);
// Replace with single item
collection.Replace(singleItem);AddRange Notification Modes:
NotifyCollectionChangedAction.Add: Notify for each added item (default)NotifyCollectionChangedAction.Reset: Single reset notificationusing DotNetTools.Wpfkit.Logging.Extensions;
using Serilog;
public class MyService
{
// Get logger for current class
private static readonly ILogger Log = LogManager.GetCurrentClassLogger();
public void DoWork()
{
Log.Me().Information("Starting work at line {LineNumber}");
try
{
// Your code here
Log.Me().Debug("Processing item");
}
catch (Exception ex)
{
Log.Me().Error(ex, "Failed to process item");
}
}
}LogManager Features:
GetCurrentClassLogger(): Automatically creates logger with calling class contextMe() extension: Adds line number information to log entriesusing Serilog;
using DotNetTools.Wpfkit.Logging.Enrichers;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.Enrich.With<UserNameEnricher>()
.WriteTo.Console()
.WriteTo.File("logs/app.log", rollingInterval: RollingInterval.Day)
.CreateLogger();using DotNetTools.Wpfkit.Database;
// Update connection string in appsettings.json
string connectionString = "Data Source=myserver;Initial Catalog=mydb;";
AppSettingsUpdater.UpdateConnectionString(connectionString);Features:
ConnectDatabase propertyappsettings.json Structure:
{
"ConnectDatabase": "path/to/database.db",
"OtherSettings": "..."
}protected bool SetProperty<T>(
ref T backingStore,
T value,
string propertyName = "",
Action onChanged = null,
Func<T, T, bool> validateValue = null)true if property changed, false otherwise| Property | Type | Description |
|---|---|---|
| Title | string | Main title text |
| Subtitle | string | Secondary descriptive text |
| Icon | string | Icon path or resource identifier |
| IsBusy | bool | Indicates if operation is in progress |
| IsNotBusy | bool | Inverse of IsBusy (auto-synchronized) |
| CanLoadMore | bool | Supports pagination scenarios |
| Header | string | Header content |
| Footer | string | Footer content |
void AddRange(IEnumerable<T> collection,
NotifyCollectionChangedAction notificationMode = Add)
void RemoveRange(IEnumerable<T> collection,
NotifyCollectionChangedAction notificationMode = Reset)
void Replace(T item)
void ReplaceRange(IEnumerable<T> collection)static ILogger GetCurrentClassLogger()
static ILogger Me(this ILogger logger, int sourceLineNumber = 0)static void UpdateConnectionString(string connectionString)DotNetTools.Wpfkit/
??? MvvM/
? ??? ObservableObject.cs # Base observable implementation
? ??? BaseViewModel.cs # Rich view model base class
? ??? ObservableRangeCollection.cs # Bulk operations collection
??? Logging/
? ??? Extensions/
? ? ??? LogManager.cs # Logger factory
? ? ??? UserName.cs # Username helper
? ??? Enrichers/
? ??? UserNameEnricher.cs # Serilog enricher
??? Database/
? ??? AppSettingsUpdater.cs # Configuration management
??? DotNetTools.Wpfkit.csproj
Contributions are welcome! Please follow these guidelines:
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)Copyright � 2025 Omotech Digital Solutions
Licensed under the MIT License.
This project is open source software created by Stanley Omoregie.
Author: Stanley Omoregie
Organization: Omotech Digital Solutions
Created: November 20, 2025
For questions, issues, or feature requests, please open an issue on the repository.
Built with ?? using .NET 10.0 and modern C# features