.NET 9.0とC#13プレビュー機能を使用した、カスタムRegionManagerによるWPFナビゲーションシステムのサンプルプロジェクトです。
- 最新技術: .NET 9.0 + C#13プレビュー機能
- カスタムRegionManager: Prism風のナビゲーションシステム
- MVVM: CommunityToolkit.Mvvmによる効率的な実装
- ナビゲーション履歴: 戻る/進む機能付きナビゲーション
- パラメータ渡し: ViewModels間のデータ連携
- 高性能DI: DryIocコンテナによる最適化
- 企業級ログ: NLogによる構造化ログ
- 例外処理: 包括的なエラーハンドリング
- 設定管理: appsettings.jsonによる外部化
- .NET 9.0 SDK (プレビュー版)
- Visual Studio 2022 (17.8以降) または VS Code
- Windows 10/11
git clone <repository-url>
cd wpf-experimental2dotnet restoredotnet build
dotnet run --project RegionManagerSampleRegionManagerSample/
├── App.xaml # アプリケーション定義
├── App.xaml.cs # DIコンテナ設定・例外ハンドリング
├── appsettings.json # 設定ファイル
├── ViewModels/
│ ├── MainWindowViewModel.cs # メインウィンドウViewModel
│ ├── MenuViewModel.cs # メニューViewModel
│ ├── View1ViewModel.cs # ビュー1のViewModel
│ └── View2ViewModel.cs # ビュー2のViewModel
├── Views/
│ ├── MainWindow.xaml # メインウィンドウ
│ ├── MenuView.xaml # メニュービュー
│ ├── View1.xaml # ビュー1
│ └── View2.xaml # ビュー2
├── Shared/
│ └── UI/
│ └── Navigation/
│ ├── RegionManager.cs # カスタムRegionManager実装
│ ├── NavigationHistory.cs # ナビゲーション履歴管理
│ ├── NavigationParameters.cs # パラメータ管理
│ └── RegionManagerExtensions.cs # 添付プロパティ
├── Resources/ # スタイルリソース
└── RegionManagerSample.csproj # プロジェクトファイル
doc/
├── RegionManager/
│ ├── RegionManager_Documentation.md # RegionManager詳細ドキュメント
│ ├── RegionManager_QuickStart.md # クイックスタートガイド
│ └── RegionManager_TechnicalSpec.md # 技術仕様書
├── communitytoolkit-mvvm-sample.md # CommunityToolkit.Mvvm解説
├── technical-details.md # 技術詳細解説
└── index.md # ドキュメント目次
| 技術 | バージョン | 用途 |
|---|---|---|
| .NET | 9.0 | フレームワーク |
| C# | 13.0 (preview) | 言語機能(部分プロパティ) |
| WPF | - | UIフレームワーク |
| CommunityToolkit.Mvvm | 8.4.0 | MVVMパターン |
| DryIoc | 6.2.0 | 高性能DIコンテナ |
| NLog | 6.0.4 | 構造化ログ |
| Microsoft.Extensions.* | 9.0.9 | 設定・ログ基盤 |
| Microsoft.Xaml.Behaviors.Wpf | 1.1.135 | XAML添付プロパティ |
// RegionManagerの基本的な使用方法
public partial class MenuViewModel : ObservableObject, INavigationAware
{
private readonly IRegionManager _regionManager;
[RelayCommand]
private void NavigateToView1()
{
var parameters = new NavigationParameters();
parameters.Add("Message", "Hello from Menu!");
_regionManager.NavigateAsync("ContentRegion", "View1", parameters);
}
[RelayCommand]
private void NavigateToView2()
{
_regionManager.NavigateAsync("ContentRegion", "View2");
}
// ナビゲーション完了時のコールバック
public void OnNavigatedTo(NavigationParameters parameters)
{
_logger.LogInformation("MenuView にナビゲーションされました");
}
}public partial class View1ViewModel : ObservableObject, INavigationAware
{
[ObservableProperty]
public partial string? ReceivedMessage { get; set; }
public void OnNavigatedTo(NavigationParameters parameters)
{
if (parameters.TryGetValue<string>("Message", out var message))
{
ReceivedMessage = message;
_logger.LogInformation("パラメータを受信: {Message}", message);
}
}
}public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
public partial bool CanGoBack { get; set; }
[ObservableProperty]
public partial bool CanGoForward { get; set; }
[RelayCommand]
private void GoBack()
{
if (_regionManager.CanGoBack("ContentRegion"))
{
_regionManager.GoBack("ContentRegion");
}
}
[RelayCommand]
private void GoForward()
{
if (_regionManager.CanGoForward("ContentRegion"))
{
_regionManager.GoForward("ContentRegion");
}
}
}private void BuildServiceProvider()
{
var services = new ServiceCollection();
services.AddSingleton<IConfiguration>(_configuration);
services.AddLogging(builder => builder.AddNLog());
var container = new Container(rules => rules.With(propertiesAndFields: PropertiesAndFields.Auto))
.WithDependencyInjectionAdapter(services);
// RegionManagerの登録
container.Register<IRegionManager, RegionManager>(Reuse.Singleton);
// ViewModelsの登録
container.Register<MainWindowViewModel>(Reuse.Singleton);
container.Register<MenuViewModel>(Reuse.Transient);
container.Register<View1ViewModel>(Reuse.Transient);
container.Register<View2ViewModel>(Reuse.Transient);
// Viewsの登録
container.Register<MainWindow>(Reuse.Transient);
container.Register<MenuView>(Reuse.Transient);
container.Register<View1>(Reuse.Transient);
container.Register<View2>(Reuse.Transient);
_serviceProvider = container.BuildServiceProvider();
}<ContentPresenter Grid.Row="1" Grid.Column="1"
navigation:RegionManagerAttachedProperties.RegionName="ContentRegion" />| 機能 | 実装状況 | 説明 |
|---|---|---|
| ナビゲーション | ✅ | ViewModels間の画面遷移 |
| パラメータ渡し | ✅ | NavigationParametersによるデータ連携 |
| 履歴管理 | ✅ | 戻る/進む機能 |
| INavigationAware | ✅ | ナビゲーション時のコールバック |
| 非同期ナビゲーション | ✅ | Task-basedナビゲーション |
| 複数Region | ✅ | 複数の独立したナビゲーション領域 |
| 実装方法 | 行数 | 削減率 |
|---|---|---|
| 従来のMVVM | ~300行 | - |
| CommunityToolkit.Mvvm + RegionManager | ~80行 | 73%削減 |
| 操作 | DryIoc | Microsoft.Extensions.DI |
|---|---|---|
| サービス解決 | 🚀 最高速 | 🐢 標準 |
| メモリ使用量 | 🟢 最小 | 🟡 標準 |
# 単体テスト実行(今後追加予定)
dotnet test
# カバレッジレポート生成
dotnet test --collect:"XPlat Code Coverage"詳細な技術解説は以下のドキュメントを参照してください:
- RegionManager詳細ドキュメント: 完全な機能説明
- クイックスタートガイド: 5分で始めるRegionManager
- 技術仕様書: 内部実装とアーキテクチャ
- CommunityToolkit.Mvvm解説: MVVMパターンの実装
- 技術詳細: 上級者向け技術解説
main: 安定版develop: 開発版feature/*: 機能追加hotfix/*: 緊急修正
feat: 新機能追加
fix: バグ修正
docs: ドキュメント更新
style: コードフォーマット
refactor: リファクタリング
test: テスト追加・修正
chore: その他の変更
- 単体テスト: xUnit + Moq
- 統合テスト: TestHost
- UI テスト: Appium
- RegionManager機能拡張:
- アニメーション付きナビゲーション
- ナビゲーションガード
- ビューキャッシュ機能
- Material Design: Material Design In XAML
- 多言語対応: リソース外部化
- テーマシステム: Light/Dark モード
- プラグイン: MEF による拡張
- CI/CD: GitHub Actions
- このリポジトリをフォーク
- 機能ブランチを作成 (
git checkout -b feature/AmazingFeature) - 変更をコミット (
git commit -m 'feat: Add some AmazingFeature') - ブランチにプッシュ (
git push origin feature/AmazingFeature) - プルリクエストを作成
このプロジェクトはMITライセンスの下で公開されています。詳細は LICENSE ファイルを参照してください。
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Wiki: プロジェクトWiki
- CommunityToolkit.Mvvm チーム
- DryIoc 開発者
- NLog コミュニティ
- Prism Library - RegionManagerのインスピレーション源
⭐ このプロジェクトが役に立った場合は、スターを付けてください!