137 lines
7.9 KiB
Markdown
137 lines
7.9 KiB
Markdown
---
|
||
source_files:
|
||
- Common/DTS.Common/Interactivity/IConfirmation.cs
|
||
- Common/DTS.Common/Interactivity/IInteractionRequest.cs
|
||
- Common/DTS.Common/Interactivity/Notification.cs
|
||
- Common/DTS.Common/Interactivity/Confirmation.cs
|
||
- Common/DTS.Common/Interactivity/INotification.cs
|
||
- Common/DTS.Common/Interactivity/IInteractionRequestAware.cs
|
||
- Common/DTS.Common/Interactivity/InteractionRequestTrigger.cs
|
||
- Common/DTS.Common/Interactivity/InteractionRequestedEventArgs.cs
|
||
- Common/DTS.Common/Interactivity/InteractionRequest.cs
|
||
generated_at: "2026-04-16T02:54:00.278627+00:00"
|
||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||
schema_version: 1
|
||
sha256: "0ff9757e59948461"
|
||
---
|
||
|
||
# Interactivity
|
||
|
||
## Documentation: DTS.Common.Interactivity Module
|
||
|
||
---
|
||
|
||
### 1. Purpose
|
||
|
||
This module provides a standardized, event-driven pattern for handling user interactions (e.g., confirmations, alerts, dialogs) in a decoupled manner—primarily intended for use with XAML-based UI frameworks (e.g., WPF, UWP) via the `Microsoft.Xaml.Behaviors` library. It defines core abstractions (`IInteractionRequest`, `INotification`, `IConfirmation`) and concrete implementations (`InteractionRequest<T>`, `Confirmation`, `Notification`) to enable view models to *request* interactions without direct coupling to the UI layer, while allowing views to respond to those requests using triggers and behaviors. The pattern supports both simple notifications and confirmations with user input (e.g., Yes/No), and ensures proper completion signaling via callbacks.
|
||
|
||
---
|
||
|
||
### 2. Public Interface
|
||
|
||
#### Interfaces
|
||
|
||
- **`INotification`**
|
||
```csharp
|
||
string Title { get; set; }
|
||
object Content { get; set; }
|
||
```
|
||
Represents a generic notification with a title and arbitrary content (e.g., message, view model). Serves as the base interface for all notification types.
|
||
|
||
- **`IConfirmation : INotification`**
|
||
```csharp
|
||
bool Confirmed { get; set; }
|
||
```
|
||
Extends `INotification` to represent a confirmation request (e.g., "Are you sure?"). The `Confirmed` property indicates whether the user accepted the action.
|
||
|
||
- **`IInteractionRequest`**
|
||
```csharp
|
||
event EventHandler<InteractionRequestedEventArgs> Raised;
|
||
```
|
||
Represents a request for user interaction. The `Raised` event is fired when an interaction is needed.
|
||
|
||
- **`IInteractionRequestAware`**
|
||
```csharp
|
||
INotification Notification { get; set; }
|
||
Action FinishInteraction { get; set; }
|
||
```
|
||
Implemented by UI elements (e.g., views, user controls) that need to be aware of and respond to an interaction request. `Notification` provides the context; `FinishInteraction` must be invoked to signal completion.
|
||
|
||
#### Classes
|
||
|
||
- **`Notification`**
|
||
```csharp
|
||
public class Notification : INotification
|
||
```
|
||
Concrete implementation of `INotification`. Provides `Title` and `Content` properties.
|
||
|
||
- **`Confirmation : Notification, IConfirmation`**
|
||
```csharp
|
||
public class Confirmation : Notification, IConfirmation
|
||
```
|
||
Extends `Notification` to support confirmation semantics. Includes the `Confirmed` property (default `false`), set by the UI to reflect user choice.
|
||
|
||
#### Event Arguments
|
||
|
||
- **`InteractionRequestedEventArgs : EventArgs`**
|
||
```csharp
|
||
public INotification Context { get; }
|
||
public Action Callback { get; }
|
||
```
|
||
Passed to event handlers when `IInteractionRequest.Raised` fires. `Context` contains the notification (e.g., `Confirmation`). `Callback` must be invoked (typically after user action) to signal interaction completion.
|
||
|
||
#### Interaction Request Implementation
|
||
|
||
- **`InteractionRequest<T> : IInteractionRequest`**
|
||
```csharp
|
||
public event EventHandler<InteractionRequestedEventArgs> Raised;
|
||
public void Raise(T context) where T : INotification
|
||
public void Raise(T context, Action<T> callback) where T : INotification
|
||
```
|
||
Generic implementation of `IInteractionRequest`. `Raise(context)` fires the `Raised` event with a no-op callback. `Raise(context, callback)` wraps the provided callback in an `Action` and passes it via `InteractionRequestedEventArgs`. *Note:* The `callback` parameter in the second `Raise` overload is of type `Action<T>`, but the `InteractionRequestedEventArgs.Callback` is `Action` (non-generic). The wrapper discards the `T` argument and invokes `callback(context)`.
|
||
|
||
#### Trigger
|
||
|
||
- **`InteractionRequestTrigger : EventTrigger`**
|
||
```csharp
|
||
protected override string GetEventName() => "Raised";
|
||
```
|
||
A behavior trigger designed to bind to `IInteractionRequest.Raised`. Overrides `GetEventName()` to always return `"Raised"`, simplifying XAML configuration (e.g., `<i:Interaction.Triggers><dts:InteractionRequestTrigger ... /></i:Interaction.Triggers>`).
|
||
|
||
---
|
||
|
||
### 3. Invariants
|
||
|
||
- **`INotification` contract**: Every `INotification` (and its derivatives) must provide non-null `Title` and `Content` *after* initialization if they are to be meaningfully displayed. However, the interface itself does not enforce non-nullability—views must handle `null` gracefully.
|
||
- **`IConfirmation.Confirmed`**: Must be set by the UI *before* invoking `FinishInteraction`. Its value reflects the user’s choice (e.g., `true` for "Yes", `false` for "No").
|
||
- **Callback invocation**: The `Callback` in `InteractionRequestedEventArgs` *must* be invoked exactly once per interaction request to avoid blocking the UI or leaking resources. The `InteractionRequest<T>.Raise` method ensures the callback is wrapped and passed correctly.
|
||
- **Generic constraint**: `InteractionRequest<T>` requires `T : INotification`. This ensures only valid notification types can be used as interaction context.
|
||
|
||
---
|
||
|
||
### 4. Dependencies
|
||
|
||
#### Dependencies *on* this module:
|
||
- **`Microsoft.Xaml.Behaviors`**: Required for `EventTrigger` base class used by `InteractionRequestTrigger`.
|
||
- **`System`**: For `EventArgs`, `Action`, and `EventHandler`.
|
||
|
||
#### Dependencies *of* this module:
|
||
- **UI Layer**: Views (e.g., XAML pages/user controls) must implement `IInteractionRequestAware` or use triggers (e.g., `InteractionRequestTrigger`) to handle interactions.
|
||
- **Consuming modules**: Any module requiring user interaction (e.g., view models) will reference and instantiate `InteractionRequest<T>` (typically `InteractionRequest<Confirmation>`).
|
||
|
||
#### Inferred usage:
|
||
- `InteractionRequest<Confirmation>` is the most common concrete instantiation (based on `Confirmation` class).
|
||
- Views likely bind `InteractionRequestAware.Notification` to the event args’ `Context` and invoke `InteractionRequestAware.FinishInteraction` after user action.
|
||
|
||
---
|
||
|
||
### 5. Gotchas
|
||
|
||
- **Callback signature mismatch**: The `InteractionRequest<T>.Raise(T context, Action<T> callback)` overload accepts `Action<T>`, but the `InteractionRequestedEventArgs.Callback` is `Action`. The wrapper `() => { if (callback != null) callback(context); }` discards the `T` argument—so the callback *cannot* inspect the `context` *as a parameter* (only via closure). This is non-intuitive; developers may expect the callback to receive the context as an argument.
|
||
- **No built-in validation**: `InteractionRequestedEventArgs` provides no mechanism to validate or reject the interaction. Views must handle invalid states internally (e.g., by not invoking `FinishInteraction`).
|
||
- **Thread-safety**: `InteractionRequest<T>` does not guarantee thread-safety for `Raised` event invocation. If raised from a non-UI thread, views must marshal to the UI thread themselves.
|
||
- **`FinishInteraction` must be called**: If a view fails to invoke `FinishInteraction`, the interaction remains "open," potentially blocking further interactions or leaving UI in an inconsistent state. This is a common source of bugs.
|
||
- **`Confirmed` default value**: `Confirmation.Confirmed` defaults to `false`. If a view does not explicitly set it (e.g., for a "Cancel" button), the interaction will be treated as unconfirmed.
|
||
- **No cancellation support**: There is no explicit cancellation token or mechanism to abort an interaction mid-process. Cancellation must be handled via custom logic (e.g., checking `CancellationRequested` on `Content`).
|
||
|
||
None identified from source alone. |