Files
ClassicAssist.Avalonia/.qoder/repowiki/en/content/Technical Architecture/UI Framework/Custom Controls Library.md
T
Beyhan Oğur d5f52cc3d3 first commit
2026-09-03 04:45:36 +03:00

16 KiB
Raw Blame History

Custom Controls Library

**Referenced Files in This Document** - [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) - [HueEntryToRectanglesValueConverter.cs](file://ClassicAssist.Avalonia/Misc/HueEntryToRectanglesValueConverter.cs) - [HuePickerWindow.axaml](file://ClassicAssist.Avalonia/Views/HuePickerWindow.axaml) - [HuePickerWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/HuePickerWindow.axaml.cs)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion

Introduction

This document describes the custom controls library built with Avalonia, focusing on four reusable controls:

  • HexDumpControl for efficient binary data visualization
  • EditTextBlock for editable text display
  • TextBoxKey for key binding input
  • HueEntryControl for color selection (via a picker window and value converter)

It explains control properties, events, styling options, integration patterns, usage examples, customization guidelines, and performance considerations—especially for complex rendering like hex dump.

Project Structure

The controls are implemented under ClassicAssist.Avalonia/Controls and related resources. Each control typically consists of an AXAML markup file and a code-behind file. Supporting converters and windows reside under ClassicAssist.Avalonia/Misc and ClassicAssist.Avalonia/Views.

graph TB
subgraph "Avalonia Controls"
HDC["HexDumpControl.axaml<br/>HexDumpControl.axaml.cs"]
EBT["EditTextBlock.axaml<br/>EditTextBlock.axaml.cs"]
TK["TextBoxKey.axaml<br/>TextBoxKey.axaml.cs"]
end
subgraph "Color Selection"
HEC["HueEntryControl (conceptual)<br/>uses HueEntryToRectanglesValueConverter"]
HPW["HuePickerWindow.axaml<br/>HuePickerWindow.axaml.cs"]
CONV["HueEntryToRectanglesValueConverter.cs"]
end
HDC --> |"renders bytes"| UI["Avalonia UI"]
EBT --> |"editable text"| UI
TK --> |"key capture"| UI
HEC --> CONV
HEC --> HPW

[No sources needed since this diagram shows conceptual structure]

Core Components

  • HexDumpControl: Displays large byte buffers as a scrollable grid of rows and columns with optional ASCII column, row headers, and selection support. Optimized for performance via virtualization and incremental updates.
  • EditTextBlock: A read-only TextBlock that can be toggled into edit mode to allow inline editing, then committed or canceled.
  • TextBoxKey: Captures keyboard input to represent key combinations (e.g., Ctrl+Shift+A), exposing a bound KeyBinding-like model.
  • HueEntryControl: Presents a hue selector entry that opens a HuePickerWindow and uses a value converter to render preview rectangles based on selected hues.

Integration pattern: Bind control properties to view models using Avalonia’s two-way bindings; expose events where appropriate; style via styles and templates.

Section sources

Architecture Overview

The controls follow a standard Avalonia pattern:

  • AXAML defines layout and visual tree
  • Code-behind exposes dependency properties and handles events
  • ViewModels bind to these properties
  • Converters transform values for display
  • Windows provide modal interactions (e.g., HuePickerWindow)
sequenceDiagram
participant VM as "ViewModel"
participant HDC as "HexDumpControl"
participant UI as "Avalonia UI"
VM->>HDC : Set Data property
HDC->>UI : Render rows/columns (virtualized)
UI-->>HDC : Scroll/Selection events
HDC-->>VM : Notify changes (events/properties)

Diagram sources

Detailed Component Analysis

HexDumpControl

Purpose: Efficiently visualize large byte arrays or streams as a hex grid with optional ASCII representation and selection.

Key responsibilities:

  • Accept a byte source and render it into a grid
  • Support scrolling, selection, and optional ASCII column
  • Provide styling hooks for colors, fonts, and cell sizes
  • Expose events for user interaction (e.g., selection changed)

Typical properties and behaviors:

  • Data: Source bytes or buffer
  • RowCount/ColumnWidth: Layout configuration
  • ShowAscii: Toggle ASCII column visibility
  • SelectedRange: Current selection range
  • Events: SelectionChanged, Scrolled, etc.

Styling options:

  • Cell background/foreground
  • Header brushes
  • Selection highlight brush
  • Font family and size for hex and ASCII cells

Usage example (conceptual):

  • Bind Data to a byte array in your ViewModel
  • Handle SelectionChanged to react to user selections
  • Style via ResourceDictionary for consistent look across app

Performance considerations:

  • Use virtualization to avoid creating all rows at once
  • Batch updates when data changes frequently
  • Avoid heavy per-cell computations; precompute if possible
  • Limit visible columns to reduce layout cost
flowchart TD
Start(["Set Data"]) --> Validate["Validate input length"]
Validate --> InitLayout["Initialize grid layout<br/>rows/columns"]
InitLayout --> Virtualize["Enable virtualization"]
Virtualize --> Render["Render visible cells"]
Render --> Interact{"User interaction?"}
Interact --> |Scroll| UpdateVisible["Update visible viewport"]
Interact --> |Select| UpdateSelection["Update selection state"]
UpdateVisible --> Render
UpdateSelection --> Render
Interact --> |No| End(["Idle"])
Render --> End

Diagram sources

Section sources

EditTextBlock

Purpose: Display text in a TextBlock-like control that can switch to an editable TextBox for inline editing.

Key responsibilities:

  • Show text in read-only mode
  • Enter edit mode on demand (e.g., double-click)
  • Commit or cancel edits
  • Keep content synchronized with a bound property

Typical properties and behaviors:

  • Text: Two-way bound text content
  • IsEditable: Toggle editability
  • EditModeTrigger: Event or command to enter edit mode
  • Events: EditingStarted, EditingEnded, TextChanged

Styling options:

  • Read-only appearance (font, padding)
  • Edit mode appearance (border, focus visuals)
  • Placeholder text styling

Usage example (conceptual):

  • Bind Text to a string property in ViewModel
  • Trigger edit mode via command or gesture
  • On commit, update ViewModel; on cancel, revert
sequenceDiagram
participant User as "User"
participant EBT as "EditTextBlock"
participant VM as "ViewModel"
User->>EBT : Double-click to edit
EBT->>EBT : Enter edit mode
User->>EBT : Type new text
EBT->>VM : Update bound Text (two-way)
User->>EBT : Press Enter or lose focus
EBT->>EBT : Exit edit mode
EBT-->>VM : Commit final value

Diagram sources

Section sources

TextBoxKey

Purpose: Capture keyboard input to represent key combinations for hotkeys or shortcuts.

Key responsibilities:

  • Capture key presses and modifiers
  • Format the combination into a readable string
  • Expose a bound KeyBinding-like model
  • Prevent default actions when capturing

Typical properties and behaviors:

  • KeyText: Displayed key combination string
  • Modifiers: Captured modifier keys
  • Events: KeyCaptured, ValidationFailed

Styling options:

  • Input border and focus visuals
  • Error state styling (invalid combinations)

Usage example (conceptual):

  • Bind KeyText to a string property in ViewModel
  • On capture, validate combination and notify ViewModel
  • Provide clear feedback for invalid inputs
flowchart TD
Start(["Focus TextBoxKey"]) --> Press["User presses keys"]
Press --> Capture["Capture key and modifiers"]
Capture --> Validate{"Valid combination?"}
Validate --> |Yes| Update["Update KeyText and notify"]
Validate --> |No| Error["Show validation error"]
Update --> End(["Ready"])
Error --> End

Diagram sources

Section sources

HueEntryControl

Purpose: Provide a compact entry for selecting hues, opening a HuePickerWindow and rendering previews using a value converter.

Key responsibilities:

  • Open HuePickerWindow to select hue(s)
  • Convert selected hues to visual rectangles for preview
  • Expose selected hue values to ViewModel

Typical properties and behaviors:

  • SelectedHues: Collection of selected hues
  • PreviewBrushes: Converted brushes for preview
  • Events: HueSelected, PickerClosed

Styling options:

  • Entry border and focus visuals
  • Preview rectangle size and spacing
  • Picker button styling

Usage example (conceptual):

  • Bind SelectedHues to a collection in ViewModel
  • Use HueEntryToRectanglesValueConverter to render preview rectangles
  • Handle HueSelected to update UI or settings
classDiagram
class HueEntryControl {
+SelectedHues
+PreviewBrushes
+OpenPicker()
}
class HueEntryToRectanglesValueConverter {
+Convert(value)
}
class HuePickerWindow {
+OnHueSelected(hue)
}
HueEntryControl --> HueEntryToRectanglesValueConverter : "uses"
HueEntryControl --> HuePickerWindow : "opens"

Diagram sources

Section sources

Dependency Analysis

  • HexDumpControl depends on Avalonia’s ItemsControl/Grid infrastructure and may rely on virtualization features for performance.
  • EditTextBlock composes TextBlock and TextBox internally, switching visibility based on edit mode.
  • TextBoxKey listens to low-level keyboard events and formats them into a display string.
  • HueEntryControl depends on HueEntryToRectanglesValueConverter and HuePickerWindow for selection and preview.
graph LR
HDC["HexDumpControl"] --> AV["Avalonia Grid/ItemsControl"]
EBT["EditTextBlock"] --> TB["TextBox"]
EBT --> TBLK["TextBlock"]
TK["TextBoxKey"] --> KEV["Keyboard Events"]
HEC["HueEntryControl"] --> CONV["HueEntryToRectanglesValueConverter"]
HEC --> HPW["HuePickerWindow"]

Diagram sources

Section sources

Performance Considerations

  • HexDumpControl:
    • Enable virtualization to avoid creating off-screen elements
    • Batch updates by replacing entire data sets rather than mutating large collections incrementally
    • Precompute ASCII representations if needed
    • Limit column count and adjust cell width to balance readability and performance
    • Debounce rapid data changes to reduce re-render frequency
  • EditTextBlock:
    • Avoid unnecessary rebinds during edit sessions
    • Use lightweight validation to prevent expensive checks on every keystroke
  • TextBoxKey:
    • Minimize event handling overhead; only process relevant key combinations
    • Cache formatted strings for repeated combinations
  • HueEntryControl:
    • Convert hues to brushes lazily and cache results
    • Limit number of preview rectangles to maintain responsiveness

[No sources needed since this section provides general guidance]

Troubleshooting Guide

Common issues and resolutions:

  • HexDumpControl not updating:
    • Ensure Data property is set on the UI thread
    • Verify virtualization is enabled and items panel supports recycling
  • EditTextBlock not committing edits:
    • Check focus management and blur handlers
    • Confirm two-way binding path is correct
  • TextBoxKey capturing wrong keys:
    • Validate modifier key detection logic
    • Ensure default actions are prevented during capture
  • HueEntryControl preview not showing:
    • Verify converter returns valid brushes
    • Confirm HuePickerWindow closes with selected hue and notifies control

Section sources

Conclusion

The custom controls library provides robust, reusable components for common UI tasks in Avalonia applications. By leveraging dependency properties, events, and converters, each control integrates cleanly with MVVM patterns. For high-performance scenarios like hex dump rendering, prioritize virtualization and batch updates. Consistent styling and clear integration patterns ensure maintainability and extensibility across the application.

[No sources needed since this section summarizes without analyzing specific files]