CG.Infrastructure.Presentation
3.10.3
See the version list below for details.
dotnet add package CG.Infrastructure.Presentation --version 3.10.3
NuGet\Install-Package CG.Infrastructure.Presentation -Version 3.10.3
<PackageReference Include="CG.Infrastructure.Presentation" Version="3.10.3" />
<PackageVersion Include="CG.Infrastructure.Presentation" Version="3.10.3" />
<PackageReference Include="CG.Infrastructure.Presentation" />
paket add CG.Infrastructure.Presentation --version 3.10.3
#r "nuget: CG.Infrastructure.Presentation, 3.10.3"
#:package CG.Infrastructure.Presentation@3.10.3
#addin nuget:?package=CG.Infrastructure.Presentation&version=3.10.3
#tool nuget:?package=CG.Infrastructure.Presentation&version=3.10.3
Infrastructure.Presentation
A .NET WPF library that provides base view models, custom controls, and presentation layer infrastructure for building modern Windows desktop applications with the MVVM pattern.
Overview
Infrastructure.Presentation is a .NET 9.0 Windows library designed to accelerate WPF application development by providing common presentation layer components, base classes, and custom controls. It integrates with the infrastructure ecosystem to deliver a consistent development experience across your applications.
Features
- Base View Models: Pre-built base classes for common MVVM patterns
- Custom Controls: Reusable WPF controls for consistent UI/UX
- MVVM Toolkit Integration: Built on CommunityToolkit.Mvvm for modern MVVM development
- Modern UI Framework: MahApps.Metro integration for Metro-style applications
- Logging Support: Integrated logging capabilities for presentation layer debugging
- Service Integration: Leverages core infrastructure services for dependency injection
- Windows-Specific: Optimized for Windows desktop applications
Target Framework
- .NET 9.0 Windows (WPF)
Dependencies
Core Dependencies
- CG.Infrastructure.Core (3.10.7) - Core infrastructure components and service extensions
- CG.Infrastructure.Services (3.10.2) - Service layer abstractions and implementations
MVVM Framework
- CommunityToolkit.Mvvm (8.4.0) - Modern MVVM toolkit with source generators
UI Framework
- MahApps.Metro (2.4.10) - Metro-style UI controls and themes for WPF
Logging
- Microsoft.Extensions.Logging (9.0.8) - Logging framework for .NET
Package Information
- Package ID: CG.Infrastructure.Presentation
- Version: 3.10.2
- Authors: Matthew Evans
- Company: Matthew Evans
- Product: CG.Infrastructure.Presentation
- Description: Infra Presentation library with base viewmodels and custom controls
- GeneratePackageOnBuild: True
Getting Started
Installation
dotnet add package CG.Infrastructure.Presentation
Basic Setup
<Application x:Class="YourApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
// Program.cs or App.xaml.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
var services = new ServiceCollection();
// Add logging
services.AddLogging(builder =>
{
builder.AddConsole();
builder.AddDebug();
});
// Add your services
services.AddSingleton<IMainViewModel, MainViewModel>();
services.AddSingleton<MainWindow>();
var serviceProvider = services.BuildServiceProvider();
Usage Examples
Base View Model
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Logging;
public partial class MainViewModel : ObservableObject
{
private readonly ILogger<MainViewModel> _logger;
[ObservableProperty]
private string _title = "Main Window";
[ObservableProperty]
private bool _isLoading;
[ObservableProperty]
private string _statusMessage = string.Empty;
public MainViewModel(ILogger<MainViewModel> logger)
{
_logger = logger;
}
[RelayCommand]
private async Task LoadDataAsync()
{
try
{
IsLoading = true;
StatusMessage = "Loading data...";
_logger.LogInformation("Starting data load operation");
// Simulate async operation
await Task.Delay(2000);
StatusMessage = "Data loaded successfully";
_logger.LogInformation("Data load completed successfully");
}
catch (Exception ex)
{
StatusMessage = "Error loading data";
_logger.LogError(ex, "Failed to load data");
}
finally
{
IsLoading = false;
}
}
[RelayCommand]
private void ClearStatus()
{
StatusMessage = string.Empty;
_logger.LogDebug("Status message cleared");
}
}
Custom Control Example
using System.Windows;
using System.Windows.Controls;
namespace YourApp.Controls
{
public class CustomButton : Button
{
static CustomButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomButton),
new FrameworkPropertyMetadata(typeof(CustomButton)));
}
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register(nameof(Icon), typeof(string), typeof(CustomButton),
new PropertyMetadata(string.Empty));
public string Icon
{
get => (string)GetValue(IconProperty);
set => SetValue(IconProperty, value);
}
}
}
Metro-Style Window
<Controls:MetroWindow x:Class="YourApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
Title="{Binding Title}"
Height="450" Width="800"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="20,20,20,10">
<TextBlock Text="Welcome to Your App"
FontSize="24"
FontWeight="Bold"
HorizontalAlignment="Center"/>
</StackPanel>
<ScrollViewer Grid.Row="1" Margin="20,10">
<StackPanel>
<Button Content="Load Data"
Command="{Binding LoadDataCommand}"
Style="{StaticResource MahApps.Styles.Button.Square}"
Margin="0,10"/>
<ProgressBar IsIndeterminate="{Binding IsLoading}"
Visibility="{Binding IsLoading, Converter={StaticResource BooleanToVisibilityConverter}}"
Margin="0,10"/>
<TextBlock Text="{Binding StatusMessage}"
Style="{StaticResource MahApps.Styles.TextBlock}"
Margin="0,10"/>
</StackPanel>
</ScrollViewer>
<StackPanel Grid.Row="2" Margin="20,10,20,20">
<Button Content="Clear Status"
Command="{Binding ClearStatusCommand}"
Style="{StaticResource MahApps.Styles.Button.Square.Transparent}"
HorizontalAlignment="Right"/>
</StackPanel>
</Grid>
</Controls:MetroWindow>
Service Integration
public class UserService
{
private readonly ILogger<UserService> _logger;
private readonly IHttpClientFactory _httpClientFactory;
public UserService(ILogger<UserService> logger, IHttpClientFactory httpClientFactory)
{
_logger = logger;
_httpClientFactory = httpClientFactory;
}
public async Task<List<User>> GetUsersAsync()
{
try
{
_logger.LogInformation("Fetching users from API");
var client = _httpClientFactory.CreateClient();
var response = await client.GetAsync("api/users");
response.EnsureSuccessStatusCode();
var users = await response.Content.ReadFromJsonAsync<List<User>>();
_logger.LogInformation("Successfully retrieved {Count} users", users?.Count ?? 0);
return users ?? new List<User>();
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to retrieve users");
throw;
}
}
}
// Register in DI container
services.AddHttpClient();
services.AddScoped<UserService>();
Advanced Features
Custom Theme Support
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="CustomPrimaryBrush" Color="#FF1976D2"/>
<SolidColorBrush x:Key="CustomAccentBrush" Color="#FFFF5722"/>
<Style x:Key="CustomButtonStyle" TargetType="Button" BasedOn="{StaticResource MahApps.Styles.Button.Square}">
<Setter Property="Background" Value="{StaticResource CustomPrimaryBrush}"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="{StaticResource CustomPrimaryBrush}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource CustomAccentBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource CustomAccentBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Data Binding with Validation
public partial class UserViewModel : ObservableValidator
{
[ObservableProperty]
[NotifyDataErrorInfo]
[Required]
[MinLength(2)]
[MaxLength(50)]
private string _firstName = string.Empty;
[ObservableProperty]
[NotifyDataErrorInfo]
[Required]
[EmailAddress]
private string _email = string.Empty;
[ObservableProperty]
[NotifyDataErrorInfo]
[Range(18, 120)]
private int _age;
[RelayCommand(CanExecute = nameof(CanSave))]
private async Task SaveAsync()
{
ValidateAllProperties();
if (HasErrors)
{
return;
}
// Save logic here
await Task.CompletedTask;
}
private bool CanSave() => !HasErrors;
}
Custom Control Templates
<ControlTemplate x:Key="CustomButtonTemplate" TargetType="Button">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="8">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="{TemplateBinding Padding}"/>
</Border>
</ControlTemplate>
Best Practices
- MVVM Pattern: Always separate view logic from business logic using view models
- Dependency Injection: Use constructor injection for services and dependencies
- Async Operations: Use async/await for I/O operations and update UI accordingly
- Logging: Include meaningful log messages for debugging and monitoring
- Error Handling: Implement proper error handling with user-friendly messages
- Resource Management: Use resource dictionaries for consistent styling
- Data Binding: Prefer data binding over code-behind for UI updates
- Testing: Write unit tests for view models and business logic
Testing
View Model Testing
[Test]
public async Task LoadDataCommand_WhenExecuted_UpdatesStatusAndLoadingState()
{
// Arrange
var mockLogger = new Mock<ILogger<MainViewModel>>();
var viewModel = new MainViewModel(mockLogger.Object);
// Act
await viewModel.LoadDataCommand.ExecuteAsync(null);
// Assert
Assert.That(viewModel.IsLoading, Is.False);
Assert.That(viewModel.StatusMessage, Is.EqualTo("Data loaded successfully"));
}
[Test]
public void ClearStatusCommand_WhenExecuted_ClearsStatusMessage()
{
// Arrange
var mockLogger = new Mock<ILogger<MainViewModel>>();
var viewModel = new MainViewModel(mockLogger.Object);
viewModel.StatusMessage = "Some status";
// Act
viewModel.ClearStatusCommand.Execute(null);
// Assert
Assert.That(viewModel.StatusMessage, Is.Empty);
}
Contributing
This project is part of the CG Infrastructure Libraries. For contributions, please refer to the main infrastructure repository guidelines.
License
See the LICENSE file in the root directory for licensing information.
Support
For issues and questions related to this library, please contact the development team or create an issue in the project repository.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0-windows7.0 is compatible. net10.0-windows was computed. |
-
net9.0-windows7.0
- CG.Infrastructure.Core (>= 3.10.7)
- CG.Infrastructure.Services (>= 3.10.2)
- CommunityToolkit.Mvvm (>= 8.4.0)
- MahApps.Metro (>= 2.4.10)
- Microsoft.Extensions.Logging (>= 9.0.8)
NuGet packages (5)
Showing the top 5 NuGet packages that depend on CG.Infrastructure.Presentation:
Package | Downloads |
---|---|
CG.Platform.Presentation
Platform Presentation library with shared services |
|
CG.Platform.ViewModels
Platform view models library with shared services |
|
CG.Platform.Views
Platform views library with shared services |
|
CG.Infrastructure.Navigating
Infra Navigating library with shared services and base viewmodels |
|
CG.Infrastructure.Navigation
Infra Navigation library with shared services and base viewmodels |
GitHub repositories
This package is not used by any popular GitHub repositories.