Oakrey.Applications.UserPrompts.Windows 1.0.1

dotnet add package Oakrey.Applications.UserPrompts.Windows --version 1.0.1
                    
NuGet\Install-Package Oakrey.Applications.UserPrompts.Windows -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Oakrey.Applications.UserPrompts.Windows" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Oakrey.Applications.UserPrompts.Windows" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Oakrey.Applications.UserPrompts.Windows" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Oakrey.Applications.UserPrompts.Windows --version 1.0.1
                    
#r "nuget: Oakrey.Applications.UserPrompts.Windows, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Oakrey.Applications.UserPrompts.Windows@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Oakrey.Applications.UserPrompts.Windows&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Oakrey.Applications.UserPrompts.Windows&version=1.0.1
                    
Install as a Cake Tool

Oakrey.Applications.UserPrompts.Windows

A standard Windows implementation of the UserPrompts.Abstractions library, using native WPF MessageBox and simple custom dialogs. This package provides a lightweight, quick-to-implement solution for user prompts with standard Windows look and feel.

Features

Native Windows MessageBox

  • Standard Windows UI: Uses built-in MessageBox for consistent Windows experience
  • Native Icons: Standard Windows icons (Information, Warning, Error, Question)
  • Familiar Design: Users get the familiar Windows dialog appearance
  • Zero Configuration: Works out-of-the-box with minimal setup

Full Prompt Type Support

  • Information Messages: Info, Warning, Error, Success, and Exception dialogs
  • Questions: Yes/No and Ok/Cancel prompts
  • Input Collection: Simple input dialogs for text entry
  • Selection Dialogs: List-based selection from multiple options

Simple Custom Dialogs

  • InputDialog: Clean input dialog for string collection
  • SelectionDialog: List-based selection dialog with double-click support

Thread-Safe UI Interaction

  • Dispatcher-based execution ensures UI thread safety
  • Async/await support for non-blocking operations

Easy Configuration

  • One-line dependency injection setup with extension method
  • Automatic dispatcher and service registration
  • Seamless integration with UserPrompts.Abstractions

Lightweight

  • Minimal dependencies
  • No custom styling overhead
  • Fast and responsive

Installation

You can install the package via NuGet Package Manager, Package Manager Console or the .NET CLI.

NuGet Package Manager

  1. Open your project in Visual Studio.
  2. Navigate to Tools > NuGet Package Manager > Manage NuGet Packages for Solution....
  3. Search for Oakrey.Applications.UserPrompts.Windows and click Install.

.NET CLI

Run the following command in your terminal:

dotnet add package Oakrey.Applications.UserPrompts.Windows

Package Manager Console

Run the following command in your Package Manager Console:

Install-Package Oakrey.Applications.UserPrompts.Windows

Prerequisites

This package requires:

  • Oakrey.Applications.UserPrompts.Abstractions - For interfaces and base types

Usage Examples

Dependency Injection Setup

using Microsoft.Extensions.DependencyInjection;
using Oakrey.Applications.UserPrompts.Windows;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Register Windows user prompts service
        services.AddUserPromptsService();
        
        // This automatically registers:
        // - WPF Application Dispatcher
        // - IUserPrompter<T> for dependency injection
        // - WindowsUserPromptService as IUserPromptBus
    }
}

Using in Your Application

using Oakrey.Applications.UserPrompts;
using Oakrey.Applications.UserPrompts.Results;

public class DocumentService
{
    private readonly IUserPrompter<DocumentService> _prompter;

    public DocumentService(IUserPrompter<DocumentService> prompter)
    {
        _prompter = prompter;
    }

    // Show information with standard Windows MessageBox
    public async Task ShowInfoAsync()
    {
        await _prompter.InfoAsync("Information", "Document saved successfully.");
    }

    // Show warning with warning icon
    public async Task ShowWarningAsync()
    {
        await _prompter.WarnAsync("Warning", "Document has unsaved changes.");
    }

    // Show error with error icon
    public async Task HandleErrorAsync(Exception ex)
    {
        await _prompter.ErrorAsync("Error", $"Failed to save document: {ex.Message}");
    }

    // Show success message (uses Information icon)
    public async Task ShowSuccessAsync()
    {
        await _prompter.SuccessAsync("Success", "Operation completed successfully!");
    }

    // Ask Yes/No question
    public async Task<bool> ConfirmDeleteAsync(string fileName)
    {
        var result = await _prompter.AskYesOrNoAsync(
            "Confirm Delete",
            $"Are you sure you want to delete '{fileName}'?");
        
        return result == Result.Yes;
    }

    // Ask Ok/Cancel question
    public async Task<bool> ConfirmSaveAsync()
    {
        var result = await _prompter.AskOkOrCancelAsync(
            "Save Changes",
            "Do you want to save changes before closing?");
        
        return result == Result.Ok;
    }

    // Get user input
    public async Task<string?> RenameFileAsync(string currentName)
    {
        var result = await _prompter.AskForStringAsync(
            "Rename File",
            $"Enter new name for '{currentName}':");
        
        if (result.Result == Result.Ok && !string.IsNullOrWhiteSpace(result.Value))
        {
            return result.Value;
        }
        
        return null;
    }

    // Select from options
    public async Task<string?> SelectEncodingAsync()
    {
        var encodings = new[] { "UTF-8", "UTF-16", "ASCII", "Windows-1252" };
        
        var result = await _prompter.AskForSelectionAsync(
            "Select Encoding",
            "Choose the file encoding:",
            encodings);
        
        if (result.Result == Result.Ok)
        {
            return result.Value;
        }
        
        return null;
    }
}

Complete WPF Application Example

using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using Oakrey.Applications.UserPrompts.Windows;

public partial class App : Application
{
    private IServiceProvider _serviceProvider;

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        var services = new ServiceCollection();
        
        // Register Windows user prompts (one line!)
        services.AddUserPromptsService();
        
        // Register your services and view models
        services.AddTransient<DocumentService>();
        services.AddTransient<MainViewModel>();
        
        _serviceProvider = services.BuildServiceProvider();
        
        var mainWindow = new MainWindow
        {
            DataContext = _serviceProvider.GetRequiredService<MainViewModel>()
        };
        
        mainWindow.Show();
    }
}

Error Handling Pattern

public async Task SaveDocumentAsync(string filePath, string content)
{
    try
    {
        // Validate before saving
        if (string.IsNullOrWhiteSpace(content))
        {
            await _prompter.WarnAsync("Warning", "Cannot save empty document.");
            return;
        }

        // Save the file
        await File.WriteAllTextAsync(filePath, content);
        
        await _prompter.SuccessAsync("Success", "Document saved successfully.");
    }
    catch (UnauthorizedAccessException)
    {
        await _prompter.ErrorAsync("Access Denied", 
            "You don't have permission to save to this location.");
    }
    catch (IOException ex)
    {
        await _prompter.ExcpetionAsync("I/O Error", 
            $"Failed to save document: {ex.Message}");
    }
    catch (Exception ex)
    {
        await _prompter.ErrorAsync("Unexpected Error", 
            $"An error occurred: {ex.Message}");
    }
}

Using MessageBoxUserPrompter Directly

// For scenarios where you don't need the bus architecture
public class SimpleService
{
    private readonly MessageBoxUserPrompter _prompter;

    public SimpleService()
    {
        _prompter = new MessageBoxUserPrompter();
    }

    public async Task ShowMessage()
    {
        await _prompter.InfoAsync("Hello", "This is a simple message box!");
    }
}

Confirmation Before Closing

public class MainViewModel
{
    private readonly IUserPrompter<MainViewModel> _prompter;
    public bool HasUnsavedChanges { get; set; }

    public MainViewModel(IUserPrompter<MainViewModel> prompter)
    {
        _prompter = prompter;
    }

    public async Task<bool> ConfirmCloseAsync()
    {
        if (!HasUnsavedChanges)
        {
            return true;
        }

        var result = await _prompter.AskYesOrNoAsync(
            "Unsaved Changes",
            "You have unsaved changes. Do you want to exit without saving?");

        return result == Result.Yes;
    }
}

Selection with Generic Types

public enum Priority
{
    Low,
    Medium,
    High,
    Critical
}

public async Task<Priority?> SelectPriorityAsync()
{
    var priorities = Enum.GetValues<Priority>();
    
    var result = await _prompter.AskForSelectionAsync(
        "Set Priority",
        "Select the task priority:",
        priorities);
    
    if (result.Result == Result.Ok && result.Value != null)
    {
        return result.Value;
    }
    
    return null;
}

Architecture

WindowsUserPromptService

The WindowsUserPromptService class implements IUserPromptBus and routes prompt requests to appropriate Windows dialogs:

  • Error ? MessageBox with MessageBoxImage.Error
  • Warning ? MessageBox with MessageBoxImage.Warning
  • Information ? MessageBox with MessageBoxImage.Information
  • Success ? MessageBox with MessageBoxImage.Information
  • WarningException ? MessageBox with MessageBoxImage.Warning
  • YesNoPrompt ? MessageBox with MessageBoxButton.YesNo
  • OkCancelPrompt ? MessageBox with MessageBoxButton.OKCancel
  • InputPrompt ? Custom InputDialog window
  • ComboPrompt ? Custom SelectionDialog window

Custom Dialogs

InputDialog
  • Simple text input dialog
  • Auto-focus on text box
  • Pre-selects existing text for easy editing
  • OK/Cancel buttons
  • Supports default values
SelectionDialog
  • List-based selection
  • Double-click to select and close
  • OK/Cancel buttons
  • Displays all options in a scrollable list

Thread Safety

All dialogs are invoked on the UI thread using the WPF Dispatcher, ensuring thread-safe operation from any thread.

Comparison with UserPrompts.Custom

Feature UserPrompts.Windows UserPrompts.Custom
Dialog Style Standard MessageBox Custom WPF controls
Visual Design Windows native style Enhanced Oakrey styling
Logging No built-in logging Integrated logging
Dependencies Minimal Requires Oakrey.UI + Oakrey.Log
Setup Complexity Very simple Simple
Styling Options Limited (Windows standard) Full customization
Best For Quick implementations, standard apps Branded applications

When to Use

Choose UserPrompts.Windows when:

  • You want a quick, simple implementation
  • Standard Windows look is acceptable
  • You prefer minimal dependencies
  • Users are familiar with standard Windows dialogs
  • You don't need custom branding

Choose UserPrompts.Custom when:

  • You need custom branding and styling
  • Integrated logging is required
  • You want consistent look across your application
  • You're already using Oakrey.UI components

Requirements

  • .NET 10 or higher
  • Windows platform (WPF)
  • Oakrey.Applications.UserPrompts.Abstractions

Project Information

Contributing

Contributions are welcome! Feel free to open issues or submit pull requests to improve the package.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net10.0-windows7.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 83 3/13/2026
1.0.0 83 3/11/2026