# Events and Callbacks

## Overview

The Events and Callbacks feature of the SiticoneLoadingSpinner control enables developers to integrate custom logic at key points in the spinner's lifecycle. The control exposes events for state changes (when the spinner starts or stops), for completing a full rotation, and for progress updates during background operations. These callbacks allow for responsive UI updates, logging, or triggering additional actions in synchronization with the spinner's animation and background processing.

***

### Detailed Events and Callbacks

The table below summarizes the primary events available, their descriptions, and the associated event argument types.

| Event / Callback    | Description                                                                                                | EventArgs Type              |
| ------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------- |
| SpinnerStateChanged | Raised whenever the spinner starts or stops, allowing developers to react to changes in its running state. | SpinnerStateEventArgs       |
| RotationCompleted   | Occurs when the spinner completes a full rotation, which can be used to trigger periodic actions.          | EventArgs (typically empty) |
| ProgressChanged     | Raised during background operations to provide progress updates, enabling real-time feedback.              | ProgressChangedEventArgs    |
| WorkCompleted       | Triggered when a background task finishes, whether through successful completion, cancellation, or error.  | RunWorkerCompletedEventArgs |

*Note: The SpinnerStateEventArgs provides a Boolean property, IsRunning, to indicate whether the spinner is active.*

***

### Code Examples & Integration Samples

#### Handling Spinner State Changes

Subscribe to the SpinnerStateChanged event to execute custom logic when the spinner starts or stops:

```csharp
// Create an instance of the spinner control.
var spinner = new SiticoneLoadingSpinner();

// Subscribe to the SpinnerStateChanged event.
spinner.SpinnerStateChanged += (sender, e) =>
{
    if (e.IsRunning)
    {
        Console.WriteLine("Spinner started.");
    }
    else
    {
        Console.WriteLine("Spinner stopped.");
    }
};

// Start and then stop the spinner.
spinner.Start();
Thread.Sleep(2000);  // Simulate some work.
spinner.Stop();
```

#### Responding to Rotation Completion

Utilize the RotationCompleted event to perform actions each time the spinner completes a full cycle:

```csharp
spinner.RotationCompleted += (sender, e) =>
{
    // Example: Log every completed rotation.
    Console.WriteLine("A full rotation has been completed.");
};
spinner.Start();
```

#### Integrating Progress Updates

Leverage the ProgressChanged event to update UI elements or log progress during background tasks:

```csharp
spinner.ProgressChanged += (sender, e) =>
{
    // Update a status label or log the progress.
    Console.WriteLine($"Progress: {e.ProgressPercentage}%");
};

// Example background task using the synchronous RunWorkerAsync overload.
spinner.RunWorkerAsync((sender, e) =>
{
    for (int i = 0; i <= 100; i++)
    {
        (sender as BackgroundWorker)?.ReportProgress(i);
        Thread.Sleep(50); // Simulate work.
    }
});
```

#### Handling Background Work Completion

Subscribe to the WorkCompleted event to determine when background operations have finished:

```csharp
spinner.WorkCompleted += (sender, e) =>
{
    if (e.Cancelled)
    {
        Console.WriteLine("Background work was cancelled.");
    }
    else if (e.Error != null)
    {
        Console.WriteLine("An error occurred: " + e.Error.Message);
    }
    else
    {
        Console.WriteLine("Background work completed successfully.");
    }
};
```

***

### Key Points

<table><thead><tr><th width="278">Aspect</th><th>Details</th></tr></thead><tbody><tr><td>Real-Time State Notifications</td><td>The SpinnerStateChanged event provides immediate feedback when the spinner's state changes (start/stop).</td></tr><tr><td>Periodic Animation Callbacks</td><td>RotationCompleted can be used to trigger actions after every complete rotation, useful for periodic tasks.</td></tr><tr><td>Progress Reporting</td><td>ProgressChanged and WorkCompleted offer detailed insights into background task execution and progress status.</td></tr><tr><td>Standard Event Patterns</td><td>Events use standard .NET event argument types, making integration straightforward and familiar to developers.</td></tr></tbody></table>

***

### Best Practices

<table><thead><tr><th width="310">Best Practice</th><th>Recommendation</th></tr></thead><tbody><tr><td>Unsubscribe When Not Needed</td><td>To prevent memory leaks, unsubscribe from events when the spinner control is disposed or when event callbacks are no longer necessary.</td></tr><tr><td>Use Clear and Concise Handlers</td><td>Keep event handlers lightweight to ensure that UI responsiveness is maintained during frequent callback events (e.g., progress updates).</td></tr><tr><td>Coordinate with Background Tasks</td><td>Ensure that progress reporting is synchronized with long-running operations to provide accurate user feedback without delays.</td></tr><tr><td>Log and Debug Effectively</td><td>Use event callbacks to log key lifecycle events, which can help diagnose issues during development and in production environments.</td></tr></tbody></table>

***

### Common Pitfalls

<table><thead><tr><th width="299">Common Issue</th><th>Explanation &#x26; Resolution</th></tr></thead><tbody><tr><td>Overloading Event Handlers</td><td>Implementing heavy logic in event callbacks may cause UI freezes; keep handlers minimal and offload processing if needed.</td></tr><tr><td>Memory Leaks from Persistent Subscriptions</td><td>Failing to unsubscribe from events when the control is no longer in use can result in memory leaks; ensure proper disposal patterns.</td></tr><tr><td>Ignoring Cancellation Feedback</td><td>Not checking for cancellation or error states in WorkCompleted may lead to unresponsive or misleading UI updates; always handle these states.</td></tr><tr><td>Misinterpreting Progress Values</td><td>Ensure that progress values reported via ProgressChanged are correctly interpreted (e.g., converting to percentage if needed).</td></tr></tbody></table>

***

### Usage Scenarios

<table><thead><tr><th width="286">Scenario</th><th>Description &#x26; Sample Code</th></tr></thead><tbody><tr><td>UI Status Updates</td><td>Update labels or progress bars in your application by handling ProgressChanged, keeping users informed during long operations.</td></tr><tr><td>Periodic Task Triggering</td><td>Use RotationCompleted to trigger periodic background checks or UI updates (e.g., refreshing data every full rotation).</td></tr><tr><td>Debugging Long-Running Tasks</td><td>Log events from WorkCompleted and ProgressChanged to help diagnose issues with long-running tasks or to provide feedback to users.</td></tr><tr><td>Dynamic UI Adjustments</td><td>Change application UI elements (such as enabling/disabling buttons) based on the spinner’s running state via SpinnerStateChanged.</td></tr></tbody></table>

***

### Review

The Events and Callbacks feature of the SiticoneLoadingSpinner control offers an event-driven approach to monitor and respond to various aspects of the spinner's operation. By providing clear notifications for state changes, rotation completions, and background progress updates, developers gain the flexibility to integrate custom logic, update UI elements, or log events in real time. This integration ensures that the spinner not only serves as a visual indicator but also as a reliable source of process feedback.

***

### Summary

The Events and Callbacks feature empowers developers to harness the full interactivity of the SiticoneLoadingSpinner control. With events such as SpinnerStateChanged, RotationCompleted, ProgressChanged, and WorkCompleted, the control provides timely notifications about its operational state and background tasks. This event-driven model enables dynamic UI responses, efficient logging, and robust error handling, ensuring a seamless and responsive user experience.

***

### Additional Tips

<table><thead><tr><th width="321">Tip</th><th>Recommendation</th></tr></thead><tbody><tr><td>Centralize Event Handling</td><td>Consider creating a dedicated event handler class or method for logging and UI updates to keep your code organized and maintainable.</td></tr><tr><td>Use Lambda Expressions Judiciously</td><td>While lambda expressions can simplify event subscriptions, ensure that they do not obscure the underlying logic for future maintainability.</td></tr><tr><td>Test Under Load</td><td>Simulate heavy background work to ensure that your event handlers maintain responsiveness and accurately reflect state changes.</td></tr><tr><td>Document Event Usage</td><td>Clearly document the intended use of each event in your codebase so that future developers understand their roles and interactions.</td></tr></tbody></table>

This comprehensive documentation for the Events and Callbacks feature should enable developers to effectively integrate, monitor, and respond to spinner state changes and background operations within their .NET WinForms applications.
