diff --git a/src/Modern.Forms/Timer.cs b/src/Modern.Forms/Timer.cs
new file mode 100644
index 0000000..e644ace
--- /dev/null
+++ b/src/Modern.Forms/Timer.cs
@@ -0,0 +1,153 @@
+using System.ComponentModel;
+using Modern.WindowKit.Threading;
+
+namespace Modern.Forms
+{
+ ///
+ /// Implements a timer that raises an event at user-defined intervals.
+ /// This timer is intended for UI-related scenarios and raises its
+ /// event on the UI thread.
+ ///
+ ///
+ /// Use this component when periodic work must be performed on the UI thread,
+ /// such as updating UI state, animations, or scheduling lightweight tasks.
+ ///
+ /// This timer uses internally and is therefore
+ /// integrated with the current UI dispatcher.
+ ///
+ public class Timer : Component
+ {
+ private DispatcherTimer? dispatcherTimer;
+ private int interval = 100;
+ private bool enabled;
+ private EventHandler? onTimer;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Timer ()
+ {
+ }
+
+ ///
+ /// Occurs when the specified timer interval has elapsed and the timer is enabled.
+ ///
+ public event EventHandler Tick {
+ add => onTimer += value;
+ remove => onTimer -= value;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the timer is running.
+ ///
+ [DefaultValue (false)]
+ public bool Enabled {
+ get => enabled;
+ set {
+ if (enabled == value)
+ return;
+
+ enabled = value;
+
+ if (enabled)
+ StartTimer ();
+ else
+ StopTimer ();
+ }
+ }
+
+ ///
+ /// Gets or sets the time, in milliseconds, between timer ticks.
+ ///
+ ///
+ /// Thrown when the value is less than 1.
+ ///
+ [DefaultValue (100)]
+ public int Interval {
+ get => interval;
+ set {
+ ArgumentOutOfRangeException.ThrowIfLessThan (value, 1);
+
+ if (interval == value)
+ return;
+
+ interval = value;
+
+ if (dispatcherTimer is not null)
+ dispatcherTimer.Interval = TimeSpan.FromMilliseconds (interval);
+ }
+ }
+
+ ///
+ /// Starts the timer.
+ ///
+ public void Start () => Enabled = true;
+
+ ///
+ /// Stops the timer.
+ ///
+ public void Stop () => Enabled = false;
+
+ ///
+ /// Raises the event.
+ ///
+ /// An that contains the event data.
+ protected virtual void OnTick (EventArgs e)
+ {
+ onTimer?.Invoke (this, e);
+ }
+
+ private void StartTimer ()
+ {
+ if (dispatcherTimer is null) {
+ dispatcherTimer = new DispatcherTimer ();
+ dispatcherTimer.Tick += DispatcherTimer_Tick;
+ }
+
+ dispatcherTimer.Interval = TimeSpan.FromMilliseconds (interval);
+ dispatcherTimer.Start ();
+ }
+
+ private void StopTimer ()
+ {
+ dispatcherTimer?.Stop ();
+ }
+
+ private void DispatcherTimer_Tick (object? sender, EventArgs e)
+ {
+ OnTick (EventArgs.Empty);
+ }
+
+ ///
+ /// Releases the resources used by the .
+ ///
+ ///
+ /// to release managed resources; otherwise, .
+ ///
+ protected override void Dispose (bool disposing)
+ {
+ if (disposing) {
+ enabled = false;
+ StopTimer ();
+
+ if (dispatcherTimer is not null) {
+ dispatcherTimer.Tick -= DispatcherTimer_Tick;
+ dispatcherTimer = null;
+ }
+
+ onTimer = null;
+ }
+
+ base.Dispose (disposing);
+ }
+
+ ///
+ /// Returns a string that represents the current timer.
+ ///
+ /// A string containing the type name and interval.
+ public override string ToString ()
+ {
+ return $"{base.ToString ()}, Interval: {Interval}";
+ }
+ }
+}