first commit
This commit is contained in:
@@ -0,0 +1,513 @@
|
||||
# UI Framework
|
||||
|
||||
<cite>
|
||||
**Referenced Files in This Document**
|
||||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||||
- [App.axaml](file://ClassicAssist.Avalonia/App.axaml)
|
||||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||||
- [MainWindow.axaml](file://ClassicAssist.Avalonia/Views/MainWindow.axaml)
|
||||
- [MainWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/MainWindow.axaml.cs)
|
||||
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
|
||||
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
|
||||
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
|
||||
- [HexDumpControl.axaml](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml)
|
||||
- [HexDumpControl.axaml.cs](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml.cs)
|
||||
- [EditTextBlock.axaml](file://ClassicAssist.Avalonia/Controls/EditTextBlock.axaml)
|
||||
- [EditTextBlock.axaml.cs](file://ClassicAssist.Avalonia/Controls/EditTextBlock.axaml.cs)
|
||||
- [TextBoxKey.axaml](file://ClassicAssist.Avalonia/Controls/TextBoxKey.axaml)
|
||||
- [TextBoxKey.axaml.cs](file://ClassicAssist.Avalonia/Controls/TextBoxKey.axaml.cs)
|
||||
- [GroupBox.Theme.xaml](file://ClassicAssist.Avalonia/Controls/GroupBox.Theme.xaml)
|
||||
- [GroupBox.cs](file://ClassicAssist.Avalonia/Controls/GroupBox.cs)
|
||||
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
- [AvalonEditBehaviour.cs](file://ClassicAssist.Avalonia/Misc/AvalonEditBehaviour.cs)
|
||||
- [CloseOnClickBehaviour.cs](file://ClassicAssist.Avalonia/Misc/CloseOnClickBehaviour.cs)
|
||||
- [ComboBoxBehavior.cs](file://ClassicAssist.Avalonia/Misc/ComboBoxBehavior.cs)
|
||||
- [DateTimeToTimeSpanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/DateTimeToTimeSpanValueConverter.cs)
|
||||
- [InverseBooleanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/InverseBooleanValueConverter.cs)
|
||||
- [JoinArrayValueConverter.cs](file://ClassicAssist.Avalonia/Misc/JoinArrayValueConverter.cs)
|
||||
- [ListBoxAutoScrollBehaviour.cs](file://ClassicAssist.Avalonia/Misc/ListBoxAutoScrollBehaviour.cs)
|
||||
- [LockStatusValueConverter.cs](file://ClassicAssist.Avalonia/Misc/LockStatusValueConverter.cs)
|
||||
- [PacketEntryBinaryValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryBinaryValueConverter.cs)
|
||||
- [PacketEntryTextValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryTextValueConverter.cs)
|
||||
- [StringToResourceConverter.cs](file://ClassicAssist.Avalonia/Misc/StringToResourceConverter.cs)
|
||||
- [WindowInitializedBehaviour.cs](file://ClassicAssist.Avalonia/Misc/WindowInitializedBehaviour.cs)
|
||||
- [WindowResizeBehaviour.cs](file://ClassicAssist.Avalonia/Misc/WindowResizeBehaviour.cs)
|
||||
- [HueEntryToRectanglesValueConverter.cs](file://ClassicAssist.Avalonia/Misc/HueEntryToRectanglesValueConverter.cs)
|
||||
- [BaseViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/BaseViewModel.cs)
|
||||
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
|
||||
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
|
||||
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
|
||||
</cite>
|
||||
|
||||
## Table of Contents
|
||||
1. [Introduction](#introduction)
|
||||
2. [Project Structure](#project-structure)
|
||||
3. [Core Components](#core-components)
|
||||
4. [Architecture Overview](#architecture-overview)
|
||||
5. [Detailed Component Analysis](#detailed-component-analysis)
|
||||
6. [Dependency Analysis](#dependency-analysis)
|
||||
7. [Performance Considerations](#performance-considerations)
|
||||
8. [Troubleshooting Guide](#troubleshooting-guide)
|
||||
9. [Conclusion](#conclusion)
|
||||
|
||||
## Introduction
|
||||
This document describes the UI framework implementation for ClassicAssist.Avalonia, focusing on the MVVM architecture with Avalonia UI, cross-platform abstractions, theme and styling, custom controls, binding system, behaviors, performance strategies, and window management. It provides a clear separation between Views, ViewModels, and Models, and explains how platform-specific implementations are abstracted to support multiple targets consistently.
|
||||
|
||||
## Project Structure
|
||||
The UI layer is organized into distinct folders that reflect MVVM responsibilities:
|
||||
- Controls: Reusable UI components (e.g., HexDumpControl, EditTextBlock, TextBoxKey).
|
||||
- Views: Window and page-level XAML views bound to ViewModels.
|
||||
- ViewModels: Presentation logic and state exposed to Views.
|
||||
- Misc: Behaviors, value converters, and cross-cutting utilities.
|
||||
- App entry points: Application lifecycle and resource initialization.
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Avalonia UI"
|
||||
Program["Program.cs"]
|
||||
App["App.axaml / App.axaml.cs"]
|
||||
MainWindow["Views/MainWindow.axaml(.cs)"]
|
||||
DialogWindow["Views/DialogWindow.axaml(.cs)"]
|
||||
end
|
||||
subgraph "Shared UI Contracts"
|
||||
IDisp["IDispatcher.cs"]
|
||||
IInv["IUIInvoker.cs"]
|
||||
BaseVM["Shared/UI/ViewModels/BaseViewModel.cs"]
|
||||
MainVM["Shared/UI/ViewModels/MainWindowViewModel.cs"]
|
||||
end
|
||||
subgraph "Custom Controls"
|
||||
Hex["Controls/HexDumpControl.axaml(.cs)"]
|
||||
EditTxt["Controls/EditTextBlock.axaml(.cs)"]
|
||||
TxtKey["Controls/TextBoxKey.axaml(.cs)"]
|
||||
GroupBox["Controls/GroupBox.cs + Theme"]
|
||||
end
|
||||
subgraph "Behaviors & Converters"
|
||||
Behav["Misc/*Behaviour.cs"]
|
||||
Conv["Misc/*ValueConverter.cs"]
|
||||
end
|
||||
Program --> App
|
||||
App --> MainWindow
|
||||
MainWindow --> MainVM
|
||||
DialogWindow --> MainVM
|
||||
MainWindow --> Hex
|
||||
MainWindow --> EditTxt
|
||||
MainWindow --> TxtKey
|
||||
MainWindow --> GroupBox
|
||||
MainWindow --> Behav
|
||||
MainWindow --> Conv
|
||||
App --> IDisp
|
||||
App --> IInv
|
||||
MainVM --> BaseVM
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||||
- [App.axaml](file://ClassicAssist.Avalonia/App.axaml)
|
||||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||||
- [MainWindow.axaml](file://ClassicAssist.Avalonia/Views/MainWindow.axaml)
|
||||
- [MainWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/MainWindow.axaml.cs)
|
||||
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
|
||||
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
|
||||
- [HexDumpControl.axaml](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml)
|
||||
- [HexDumpControl.axaml.cs](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml.cs)
|
||||
- [EditTextBlock.axaml](file://ClassicAssist.Avalonia/Controls/EditTextBlock.axaml)
|
||||
- [EditTextBlock.axaml.cs](file://ClassicAssist.Avalonia/Controls/EditTextBlock.axaml.cs)
|
||||
- [TextBoxKey.axaml](file://ClassicAssist.Avalonia/Controls/TextBoxKey.axaml)
|
||||
- [TextBoxKey.axaml.cs](file://ClassicAssist.Avalonia/Controls/TextBoxKey.axaml.cs)
|
||||
- [GroupBox.cs](file://ClassicAssist.Avalonia/Controls/GroupBox.cs)
|
||||
- [GroupBox.Theme.xaml](file://ClassicAssist.Avalonia/Controls/GroupBox.Theme.xaml)
|
||||
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
- [AvalonEditBehaviour.cs](file://ClassicAssist.Avalonia/Misc/AvalonEditBehaviour.cs)
|
||||
- [CloseOnClickBehaviour.cs](file://ClassicAssist.Avalonia/Misc/CloseOnClickBehaviour.cs)
|
||||
- [ComboBoxBehavior.cs](file://ClassicAssist.Avalonia/Misc/ComboBoxBehavior.cs)
|
||||
- [DateTimeToTimeSpanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/DateTimeToTimeSpanValueConverter.cs)
|
||||
- [InverseBooleanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/InverseBooleanValueConverter.cs)
|
||||
- [JoinArrayValueConverter.cs](file://ClassicAssist.Avalonia/Misc/JoinArrayValueConverter.cs)
|
||||
- [ListBoxAutoScrollBehaviour.cs](file://ClassicAssist.Avalonia/Misc/ListBoxAutoScrollBehaviour.cs)
|
||||
- [LockStatusValueConverter.cs](file://ClassicAssist.Avalonia/Misc/LockStatusValueConverter.cs)
|
||||
- [PacketEntryBinaryValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryBinaryValueConverter.cs)
|
||||
- [PacketEntryTextValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryTextValueConverter.cs)
|
||||
- [StringToResourceConverter.cs](file://ClassicAssist.Avalonia/Misc/StringToResourceConverter.cs)
|
||||
- [WindowInitializedBehaviour.cs](file://ClassicAssist.Avalonia/Misc/WindowInitializedBehaviour.cs)
|
||||
- [WindowResizeBehaviour.cs](file://ClassicAssist.Avalonia/Misc/WindowResizeBehaviour.cs)
|
||||
- [HueEntryToRectanglesValueConverter.cs](file://ClassicAssist.Avalonia/Misc/HueEntryToRectanglesValueConverter.cs)
|
||||
- [BaseViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/BaseViewModel.cs)
|
||||
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
|
||||
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
|
||||
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
|
||||
|
||||
**Section sources**
|
||||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||||
- [App.axaml](file://ClassicAssist.Avalonia/App.axaml)
|
||||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||||
- [MainWindow.axaml](file://ClassicAssist.Avalonia/Views/MainWindow.axaml)
|
||||
- [MainWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/MainWindow.axaml.cs)
|
||||
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
|
||||
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
|
||||
- [HexDumpControl.axaml](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml)
|
||||
- [HexDumpControl.axaml.cs](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml.cs)
|
||||
- [EditTextBlock.axaml](file://ClassicAssist.Avalonia/Controls/EditTextBlock.axaml)
|
||||
- [EditTextBlock.axaml.cs](file://ClassicAssist.Avalonia/Controls/EditTextBlock.axaml.cs)
|
||||
- [TextBoxKey.axaml](file://ClassicAssist.Avalonia/Controls/TextBoxKey.axaml)
|
||||
- [TextBoxKey.axaml.cs](file://ClassicAssist.Avalonia/Controls/TextBoxKey.axaml.cs)
|
||||
- [GroupBox.cs](file://ClassicAssist.Avalonia/Controls/GroupBox.cs)
|
||||
- [GroupBox.Theme.xaml](file://ClassicAssist.Avalonia/Controls/GroupBox.Theme.xaml)
|
||||
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
- [AvalonEditBehaviour.cs](file://ClassicAssist.Avalonia/Misc/AvalonEditBehaviour.cs)
|
||||
- [CloseOnClickBehaviour.cs](file://ClassicAssist.Avalonia/Misc/CloseOnClickBehaviour.cs)
|
||||
- [ComboBoxBehavior.cs](file://ClassicAssist.Avalonia/Misc/ComboBoxBehavior.cs)
|
||||
- [DateTimeToTimeSpanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/DateTimeToTimeSpanValueConverter.cs)
|
||||
- [InverseBooleanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/InverseBooleanValueConverter.cs)
|
||||
- [JoinArrayValueConverter.cs](file://ClassicAssist.Avalonia/Misc/JoinArrayValueConverter.cs)
|
||||
- [ListBoxAutoScrollBehaviour.cs](file://ClassicAssist.Avalonia/Misc/ListBoxAutoScrollBehaviour.cs)
|
||||
- [LockStatusValueConverter.cs](file://ClassicAssist.Avalonia/Misc/LockStatusValueConverter.cs)
|
||||
- [PacketEntryBinaryValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryBinaryValueConverter.cs)
|
||||
- [PacketEntryTextValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryTextValueConverter.cs)
|
||||
- [StringToResourceConverter.cs](file://ClassicAssist.Avalonia/Misc/StringToResourceConverter.cs)
|
||||
- [WindowInitializedBehaviour.cs](file://ClassicAssist.Avalonia/Misc/WindowInitializedBehaviour.cs)
|
||||
- [WindowResizeBehaviour.cs](file://ClassicAssist.Avalonia/Misc/WindowResizeBehaviour.cs)
|
||||
- [HueEntryToRectanglesValueConverter.cs](file://ClassicAssist.Avalonia/Misc/HueEntryToRectanglesValueConverter.cs)
|
||||
- [BaseViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/BaseViewModel.cs)
|
||||
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
|
||||
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
|
||||
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
|
||||
|
||||
## Core Components
|
||||
- Application bootstrap and DI setup: The application initializes resources, registers services, and creates the main window.
|
||||
- Cross-platform dispatching and UI invocation: Abstractions for thread marshaling and UI operations ensure consistent behavior across platforms.
|
||||
- Custom controls: Specialized controls for hex editing, key input, and text editing with rich UX.
|
||||
- Behaviors and converters: Declarative enhancements to standard controls and data transformations.
|
||||
- Window management: Centralized dialog handling and modal workflows.
|
||||
|
||||
**Section sources**
|
||||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||||
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
- [HexDumpControl.axaml.cs](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml.cs)
|
||||
- [EditTextBlock.axaml.cs](file://ClassicAssist.Avalonia/Controls/EditTextBlock.axaml.cs)
|
||||
- [TextBoxKey.axaml.cs](file://ClassicAssist.Avalonia/Controls/TextBoxKey.axaml.cs)
|
||||
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
|
||||
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
|
||||
|
||||
## Architecture Overview
|
||||
The UI follows MVVM with Avalonia:
|
||||
- Views declare layout and bind to ViewModels.
|
||||
- ViewModels expose state and commands, implementing change notifications.
|
||||
- Models encapsulate domain data and business rules.
|
||||
- Cross-platform abstractions isolate platform-specific concerns behind shared interfaces.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class IDispatcher {
|
||||
+Invoke(action)
|
||||
+BeginInvoke(action)
|
||||
}
|
||||
class IUIInvoker {
|
||||
+ShowDialog(window, viewModel)
|
||||
+ShowWindow(window, viewModel)
|
||||
}
|
||||
class AvaloniaDispatcher
|
||||
class AvaloniaUIInvoker
|
||||
class BaseViewModel {
|
||||
+NotifyPropertyChanged()
|
||||
}
|
||||
class MainWindowViewModel
|
||||
class MainWindow
|
||||
class DialogWindow
|
||||
class DialogWindowViewModel
|
||||
AvaloniaDispatcher ..|> IDispatcher
|
||||
AvaloniaUIInvoker ..|> IUIInvoker
|
||||
MainWindowViewModel --|> BaseViewModel
|
||||
MainWindow --> MainWindowViewModel : "DataContext"
|
||||
DialogWindow --> DialogWindowViewModel : "DataContext"
|
||||
MainWindow --> AvaloniaUIInvoker : "uses"
|
||||
MainWindow --> AvaloniaDispatcher : "uses"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
|
||||
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
|
||||
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
- [BaseViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/BaseViewModel.cs)
|
||||
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
|
||||
- [MainWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/MainWindow.axaml.cs)
|
||||
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
|
||||
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
|
||||
|
||||
## Detailed Component Analysis
|
||||
|
||||
### MVVM Implementation
|
||||
- BaseViewModel provides common change notification and property helpers.
|
||||
- MainWindowViewModel orchestrates UI state and delegates to services via abstractions.
|
||||
- Views bind to properties and commands; they remain thin and declarative.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User as "User"
|
||||
participant View as "MainWindow"
|
||||
participant VM as "MainWindowViewModel"
|
||||
participant Invoker as "AvaloniaUIInvoker"
|
||||
participant Dialog as "DialogWindow"
|
||||
User->>View : Click action
|
||||
View->>VM : Execute command
|
||||
VM->>Invoker : ShowDialog(dialogVM)
|
||||
Invoker->>Dialog : Create and show modal
|
||||
Dialog-->>VM : Result callback
|
||||
VM-->>View : Update UI state
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MainWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/MainWindow.axaml.cs)
|
||||
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
|
||||
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
|
||||
|
||||
**Section sources**
|
||||
- [BaseViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/BaseViewModel.cs)
|
||||
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
|
||||
- [MainWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/MainWindow.axaml.cs)
|
||||
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
|
||||
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
|
||||
|
||||
### Cross-Platform UI Abstraction Layer
|
||||
- IDispatcher and IUIInvoker define contracts for UI threading and window/dialog operations.
|
||||
- AvaloniaDispatcher implements dispatcher semantics for Avalonia’s UI thread.
|
||||
- AvaloniaUIInvoker implements cross-platform dialog/window presentation using Avalonia primitives.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["UI Operation"]) --> CheckThread["Check current thread"]
|
||||
CheckThread --> IsUIThread{"Is UI thread?"}
|
||||
IsUIThread --> |Yes| Execute["Execute directly"]
|
||||
IsUIThread --> |No| Marshal["Marshal to UI thread"]
|
||||
Marshal --> Execute
|
||||
Execute --> End(["Done"])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
|
||||
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
|
||||
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
|
||||
**Section sources**
|
||||
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
|
||||
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
|
||||
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
|
||||
### Theme System, Styling, and Resources
|
||||
- Global styles and themes are defined in XAML resources and merged at app startup.
|
||||
- Control-specific themes (e.g., GroupBox) provide default look-and-feel.
|
||||
- Resource dictionaries centralize colors, icons, and reusable styles.
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
AppRes["App.axaml resources"] --> Merged["Merged Dictionaries"]
|
||||
Merged --> Themes["Themes (Dark/Light)"]
|
||||
Merged --> Styles["Global Styles"]
|
||||
Merged --> Icons["Icons & Assets"]
|
||||
Themes --> Controls["Controls (e.g., GroupBox)"]
|
||||
Styles --> Controls
|
||||
Icons --> Controls
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [App.axaml](file://ClassicAssist.Avalonia/App.axaml)
|
||||
- [GroupBox.Theme.xaml](file://ClassicAssist.Avalonia/Controls/GroupBox.Theme.xaml)
|
||||
|
||||
**Section sources**
|
||||
- [App.axaml](file://ClassicAssist.Avalonia/App.axaml)
|
||||
- [GroupBox.Theme.xaml](file://ClassicAssist.Avalonia/Controls/GroupBox.Theme.xaml)
|
||||
|
||||
### Custom Controls Library
|
||||
- HexDumpControl: A specialized control for binary/hex inspection with efficient rendering patterns suitable for large datasets.
|
||||
- EditTextBlock: An editable text block combining read-only display with inline editing capabilities.
|
||||
- TextBoxKey: A key-binding capture control for hotkey configuration.
|
||||
- GroupBox: A themed container control with consistent styling.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class HexDumpControl {
|
||||
+Data
|
||||
+Refresh()
|
||||
}
|
||||
class EditTextBlock {
|
||||
+Text
|
||||
+EditMode(bool)
|
||||
}
|
||||
class TextBoxKey {
|
||||
+KeyBinding
|
||||
+CaptureKey()
|
||||
}
|
||||
class GroupBox {
|
||||
+Header
|
||||
}
|
||||
HexDumpControl <.. EditTextBlock : "used by"
|
||||
HexDumpControl <.. TextBoxKey : "used by"
|
||||
GroupBox <.. HexDumpControl : "wraps"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [HexDumpControl.axaml.cs](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml.cs)
|
||||
- [EditTextBlock.axaml.cs](file://ClassicAssist.Avalonia/Controls/EditTextBlock.axaml.cs)
|
||||
- [TextBoxKey.axaml.cs](file://ClassicAssist.Avalonia/Controls/TextBoxKey.axaml.cs)
|
||||
- [GroupBox.cs](file://ClassicAssist.Avalonia/Controls/GroupBox.cs)
|
||||
|
||||
**Section sources**
|
||||
- [HexDumpControl.axaml](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml)
|
||||
- [HexDumpControl.axaml.cs](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml.cs)
|
||||
- [EditTextBlock.axaml](file://ClassicAssist.Avalonia/Controls/EditTextBlock.axaml)
|
||||
- [EditTextBlock.axaml.cs](file://ClassicAssist.Avalonia/Controls/EditTextBlock.axaml.cs)
|
||||
- [TextBoxKey.axaml](file://ClassicAssist.Avalonia/Controls/TextBoxKey.axaml)
|
||||
- [TextBoxKey.axaml.cs](file://ClassicAssist.Avalonia/Controls/TextBoxKey.axaml.cs)
|
||||
- [GroupBox.cs](file://ClassicAssist.Avalonia/Controls/GroupBox.cs)
|
||||
- [GroupBox.Theme.xaml](file://ClassicAssist.Avalonia/Controls/GroupBox.Theme.xaml)
|
||||
|
||||
### Binding System, Value Converters, and Behaviors
|
||||
- ValueConverters transform data for display (e.g., DateTime to TimeSpan, lock status, packet entries, string-to-resource lookup).
|
||||
- Behaviors add interactivity without code-behind (e.g., auto-scroll, close-on-click, combo box behavior, window resize/initialized hooks).
|
||||
- Bindings connect View properties to ViewModel commands and properties.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Data["ViewModel Property"] --> Converter["ValueConverter"]
|
||||
Converter --> ViewProp["View Property"]
|
||||
Behavior["Behavior"] --> View["View Element"]
|
||||
Behavior --> Event["Event/Action"]
|
||||
Event --> Command["Command in ViewModel"]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [DateTimeToTimeSpanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/DateTimeToTimeSpanValueConverter.cs)
|
||||
- [InverseBooleanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/InverseBooleanValueConverter.cs)
|
||||
- [JoinArrayValueConverter.cs](file://ClassicAssist.Avalonia/Misc/JoinArrayValueConverter.cs)
|
||||
- [LockStatusValueConverter.cs](file://ClassicAssist.Avalonia/Misc/LockStatusValueConverter.cs)
|
||||
- [PacketEntryBinaryValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryBinaryValueConverter.cs)
|
||||
- [PacketEntryTextValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryTextValueConverter.cs)
|
||||
- [StringToResourceConverter.cs](file://ClassicAssist.Avalonia/Misc/StringToResourceConverter.cs)
|
||||
- [HueEntryToRectanglesValueConverter.cs](file://ClassicAssist.Avalonia/Misc/HueEntryToRectanglesValueConverter.cs)
|
||||
- [AvalonEditBehaviour.cs](file://ClassicAssist.Avalonia/Misc/AvalonEditBehaviour.cs)
|
||||
- [CloseOnClickBehaviour.cs](file://ClassicAssist.Avalonia/Misc/CloseOnClickBehaviour.cs)
|
||||
- [ComboBoxBehavior.cs](file://ClassicAssist.Avalonia/Misc/ComboBoxBehavior.cs)
|
||||
- [ListBoxAutoScrollBehaviour.cs](file://ClassicAssist.Avalonia/Misc/ListBoxAutoScrollBehaviour.cs)
|
||||
- [WindowInitializedBehaviour.cs](file://ClassicAssist.Avalonia/Misc/WindowInitializedBehaviour.cs)
|
||||
- [WindowResizeBehaviour.cs](file://ClassicAssist.Avalonia/Misc/WindowResizeBehaviour.cs)
|
||||
|
||||
**Section sources**
|
||||
- [DateTimeToTimeSpanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/DateTimeToTimeSpanValueConverter.cs)
|
||||
- [InverseBooleanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/InverseBooleanValueConverter.cs)
|
||||
- [JoinArrayValueConverter.cs](file://ClassicAssist.Avalonia/Misc/JoinArrayValueConverter.cs)
|
||||
- [LockStatusValueConverter.cs](file://ClassicAssist.Avalonia/Misc/LockStatusValueConverter.cs)
|
||||
- [PacketEntryBinaryValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryBinaryValueConverter.cs)
|
||||
- [PacketEntryTextValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryTextValueConverter.cs)
|
||||
- [StringToResourceConverter.cs](file://ClassicAssist.Avalonia/Misc/StringToResourceConverter.cs)
|
||||
- [HueEntryToRectanglesValueConverter.cs](file://ClassicAssist.Avalonia/Misc/HueEntryToRectanglesValueConverter.cs)
|
||||
- [AvalonEditBehaviour.cs](file://ClassicAssist.Avalonia/Misc/AvalonEditBehaviour.cs)
|
||||
- [CloseOnClickBehaviour.cs](file://ClassicAssist.Avalonia/Misc/CloseOnClickBehaviour.cs)
|
||||
- [ComboBoxBehavior.cs](file://ClassicAssist.Avalonia/Misc/ComboBoxBehavior.cs)
|
||||
- [ListBoxAutoScrollBehaviour.cs](file://ClassicAssist.Avalonia/Misc/ListBoxAutoScrollBehaviour.cs)
|
||||
- [WindowInitializedBehaviour.cs](file://ClassicAssist.Avalonia/Misc/WindowInitializedBehaviour.cs)
|
||||
- [WindowResizeBehaviour.cs](file://ClassicAssist.Avalonia/Misc/WindowResizeBehaviour.cs)
|
||||
|
||||
### Window Management and Modal Dialogs
|
||||
- DialogWindow provides a standardized modal dialog shell.
|
||||
- DialogWindowViewModel coordinates dialog content and results.
|
||||
- AvaloniaUIInvoker handles creation and lifetime of dialogs/windows uniformly across platforms.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Caller as "Caller ViewModel"
|
||||
participant Invoker as "AvaloniaUIInvoker"
|
||||
participant Win as "DialogWindow"
|
||||
participant VM as "DialogWindowViewModel"
|
||||
Caller->>Invoker : ShowDialog(VM)
|
||||
Invoker->>Win : Instantiate and set DataContext
|
||||
Win->>VM : Initialize and render
|
||||
VM-->>Caller : Return result on close
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
|
||||
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
|
||||
|
||||
**Section sources**
|
||||
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
|
||||
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
|
||||
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
|
||||
## Dependency Analysis
|
||||
- Views depend on ViewModels through DataContext bindings.
|
||||
- ViewModels depend on shared base classes and abstractions (dispatcher, invoker).
|
||||
- Custom controls encapsulate complex UI logic and can be reused across views.
|
||||
- Behaviors and converters are loosely coupled and applied declaratively.
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
Views["Views"] --> VMs["ViewModels"]
|
||||
VMs --> SharedVM["BaseViewModel"]
|
||||
VMs --> Abstractions["IDispatcher / IUIInvoker"]
|
||||
Views --> Controls["Custom Controls"]
|
||||
Views --> Misc["Behaviors & Converters"]
|
||||
Controls --> Theming["Theme Resources"]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MainWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/MainWindow.axaml.cs)
|
||||
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
|
||||
- [BaseViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/BaseViewModel.cs)
|
||||
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
|
||||
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
|
||||
- [HexDumpControl.axaml.cs](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml.cs)
|
||||
- [GroupBox.Theme.xaml](file://ClassicAssist.Avalonia/Controls/GroupBox.Theme.xaml)
|
||||
|
||||
**Section sources**
|
||||
- [MainWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/MainWindow.axaml.cs)
|
||||
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
|
||||
- [BaseViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/BaseViewModel.cs)
|
||||
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
|
||||
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
|
||||
- [HexDumpControl.axaml.cs](file://ClassicAssist.Avalonia/Controls/HexDumpControl.axaml.cs)
|
||||
- [GroupBox.Theme.xaml](file://ClassicAssist.Avalonia/Controls/GroupBox.Theme.xaml)
|
||||
|
||||
## Performance Considerations
|
||||
- Virtualization: Prefer virtualizing panels for large lists to reduce memory and improve scroll performance.
|
||||
- Incremental updates: Batch collection changes and avoid excessive property notifications during bulk operations.
|
||||
- Efficient rendering: Use custom controls like HexDumpControl optimized for large binary data; avoid heavy per-item visuals.
|
||||
- Debounced input: For text inputs and key capture, debounce or throttle events to prevent UI thrashing.
|
||||
- Resource caching: Cache computed values and converter outputs where appropriate to minimize recomputation.
|
||||
- Responsive design: Use flexible layouts and responsive sizing to adapt to different screen sizes and DPI settings.
|
||||
|
||||
[No sources needed since this section provides general guidance]
|
||||
|
||||
## Troubleshooting Guide
|
||||
- Threading issues: Ensure UI updates occur on the UI thread using the dispatcher abstraction.
|
||||
- Dialog not closing: Verify that dialog results are properly returned and handled by the caller ViewModel.
|
||||
- Style conflicts: Check resource dictionary merge order and control theme overrides.
|
||||
- Converter errors: Validate input types and handle nulls gracefully in converters.
|
||||
- Memory growth: Monitor large collections and enable virtualization; dispose of unused resources.
|
||||
|
||||
**Section sources**
|
||||
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
|
||||
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
|
||||
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
|
||||
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
|
||||
- [GroupBox.Theme.xaml](file://ClassicAssist.Avalonia/Controls/GroupBox.Theme.xaml)
|
||||
- [DateTimeToTimeSpanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/DateTimeToTimeSpanValueConverter.cs)
|
||||
- [InverseBooleanValueConverter.cs](file://ClassicAssist.Avalonia/Misc/InverseBooleanValueConverter.cs)
|
||||
- [JoinArrayValueConverter.cs](file://ClassicAssist.Avalonia/Misc/JoinArrayValueConverter.cs)
|
||||
- [LockStatusValueConverter.cs](file://ClassicAssist.Avalonia/Misc/LockStatusValueConverter.cs)
|
||||
- [PacketEntryBinaryValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryBinaryValueConverter.cs)
|
||||
- [PacketEntryTextValueConverter.cs](file://ClassicAssist.Avalonia/Misc/PacketEntryTextValueConverter.cs)
|
||||
- [StringToResourceConverter.cs](file://ClassicAssist.Avalonia/Misc/StringToResourceConverter.cs)
|
||||
- [HueEntryToRectanglesValueConverter.cs](file://ClassicAssist.Avalonia/Misc/HueEntryToRectanglesValueConverter.cs)
|
||||
|
||||
## Conclusion
|
||||
ClassicAssist.Avalonia implements a clean MVVM architecture with Avalonia UI, providing robust cross-platform abstractions, a comprehensive theming system, reusable custom controls, and a rich set of behaviors and converters. The design emphasizes separation of concerns, testability, and performance, making it suitable for complex desktop applications requiring responsive and maintainable UI layers.
|
||||
Reference in New Issue
Block a user