Sfoglia il codice sorgente

REMOVED RESPONDER!

Tig 8 mesi fa
parent
commit
8d41641928

+ 0 - 65
Terminal.Gui/Input/Responder.cs

@@ -1,65 +0,0 @@
-using System.Reflection;
-
-namespace Terminal.Gui;
-
-/// <summary>Responder base class implemented by objects that want to participate on keyboard and mouse input.</summary>
-public class Responder : IDisposable
-{
-    private bool _disposedValue;
-
-    /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resource.</summary>
-
-    public void Dispose ()
-    {
-        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
-        Disposing?.Invoke (this, EventArgs.Empty);
-        Dispose (true);
-        GC.SuppressFinalize (this);
-#if DEBUG_IDISPOSABLE
-        WasDisposed = true;
-
-        foreach (Responder instance in Instances.Where (x => x.WasDisposed).ToList ())
-        {
-            Instances.Remove (instance);
-        }
-#endif
-    }
-
-    /// <summary>Event raised when <see cref="Dispose()"/> has been called to signal that this object is being disposed.</summary>
-    [CanBeNull]
-    public event EventHandler Disposing;
-
-    /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
-    /// <remarks>
-    ///     If disposing equals true, the method has been called directly or indirectly by a user's code. Managed and
-    ///     unmanaged resources can be disposed. If disposing equals false, the method has been called by the runtime from
-    ///     inside the finalizer and you should not reference other objects. Only unmanaged resources can be disposed.
-    /// </remarks>
-    /// <param name="disposing"></param>
-    protected virtual void Dispose (bool disposing)
-    {
-        if (!_disposedValue)
-        {
-            if (disposing)
-            {
-                // TODO: dispose managed state (managed objects)
-            }
-
-            _disposedValue = true;
-        }
-    }
-
-#if DEBUG_IDISPOSABLE
-    /// <summary>For debug purposes to verify objects are being disposed properly</summary>
-    public bool WasDisposed;
-
-    /// <summary>For debug purposes to verify objects are being disposed properly</summary>
-    public int DisposedCount = 0;
-
-    /// <summary>For debug purposes</summary>
-    public static List<Responder> Instances = new ();
-
-    /// <summary>For debug purposes</summary>
-    public Responder () { Instances.Add (this); }
-#endif
-}

+ 62 - 6
Terminal.Gui/View/View.cs

@@ -74,8 +74,10 @@ namespace Terminal.Gui;
 ///         To flag the entire view for redraw call <see cref="SetNeedsDraw()"/>.
 ///         To flag the entire view for redraw call <see cref="SetNeedsDraw()"/>.
 ///     </para>
 ///     </para>
 ///     <para>
 ///     <para>
-///         The <see cref="SetNeedsLayout"/> method is called when the size or layout of a view has changed. The <see cref="MainLoop"/> will
-///         cause <see cref="Layout()"/> to be called on the next <see cref="Application.Iteration"/> so there is normally no reason to direclty call
+///         The <see cref="SetNeedsLayout"/> method is called when the size or layout of a view has changed. The
+///         <see cref="MainLoop"/> will
+///         cause <see cref="Layout()"/> to be called on the next <see cref="Application.Iteration"/> so there is normally
+///         no reason to direclty call
 ///         see <see cref="Layout()"/>.
 ///         see <see cref="Layout()"/>.
 ///     </para>
 ///     </para>
 ///     <para>
 ///     <para>
@@ -107,7 +109,7 @@ namespace Terminal.Gui;
 
 
 #endregion API Docs
 #endregion API Docs
 
 
-public partial class View : Responder, ISupportInitializeNotification
+public partial class View : IDisposable, ISupportInitializeNotification
 {
 {
     #region Constructors and Initialization
     #region Constructors and Initialization
 
 
@@ -135,6 +137,10 @@ public partial class View : Responder, ISupportInitializeNotification
     /// </remarks>
     /// </remarks>
     public View ()
     public View ()
     {
     {
+#if DEBUG_IDISPOSABLE
+        Instances.Add (this);
+#endif
+
         SetupAdornments ();
         SetupAdornments ();
 
 
         SetupCommands ();
         SetupCommands ();
@@ -524,8 +530,16 @@ public partial class View : Responder, ISupportInitializeNotification
     /// <returns></returns>
     /// <returns></returns>
     public override string ToString () { return $"{GetType ().Name}({Id}){Frame}"; }
     public override string ToString () { return $"{GetType ().Name}({Id}){Frame}"; }
 
 
-    /// <inheritdoc/>
-    protected override void Dispose (bool disposing)
+    private bool _disposedValue;
+
+    /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
+    /// <remarks>
+    ///     If disposing equals true, the method has been called directly or indirectly by a user's code. Managed and
+    ///     unmanaged resources can be disposed. If disposing equals false, the method has been called by the runtime from
+    ///     inside the finalizer and you should not reference other objects. Only unmanaged resources can be disposed.
+    /// </remarks>
+    /// <param name="disposing"></param>
+    protected virtual void Dispose (bool disposing)
     {
     {
         LineCanvas.Dispose ();
         LineCanvas.Dispose ();
 
 
@@ -540,7 +554,49 @@ public partial class View : Responder, ISupportInitializeNotification
             subview.Dispose ();
             subview.Dispose ();
         }
         }
 
 
-        base.Dispose (disposing);
+        if (!_disposedValue)
+        {
+            if (disposing)
+            {
+                // TODO: dispose managed state (managed objects)
+            }
+
+            _disposedValue = true;
+        }
+
         Debug.Assert (InternalSubviews.Count == 0);
         Debug.Assert (InternalSubviews.Count == 0);
     }
     }
+
+    /// <summary>
+    ///     Riased when the <see cref="View"/> is being disposed. 
+    /// </summary>
+    public event EventHandler? Disposing;
+
+    /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resource.</summary>
+    public void Dispose ()
+    {
+        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+        Disposing?.Invoke (this, EventArgs.Empty);
+        Dispose (true);
+        GC.SuppressFinalize (this);
+#if DEBUG_IDISPOSABLE
+        WasDisposed = true;
+
+        foreach (View instance in Instances.Where (x => x.WasDisposed).ToList ())
+        {
+            Instances.Remove (instance);
+        }
+#endif
+    }
+
+#if DEBUG_IDISPOSABLE
+    /// <summary>For debug purposes to verify objects are being disposed properly</summary>
+    public bool WasDisposed { get; set; }
+
+    /// <summary>For debug purposes to verify objects are being disposed properly</summary>
+    public int DisposedCount { get; set; } = 0;
+
+    /// <summary>For debug purposes</summary>
+    public static List<View> Instances { get; set; } = [];
+#endif
 }
 }

+ 2 - 2
UICatalog/UICatalog.cs

@@ -607,12 +607,12 @@ public class UICatalogApp
         // Validate there are no outstanding Responder-based instances 
         // Validate there are no outstanding Responder-based instances 
         // after a scenario was selected to run. This proves the main UI Catalog
         // after a scenario was selected to run. This proves the main UI Catalog
         // 'app' closed cleanly.
         // 'app' closed cleanly.
-        foreach (Responder? inst in Responder.Instances)
+        foreach (View? inst in View.Instances)
         {
         {
             Debug.Assert (inst.WasDisposed);
             Debug.Assert (inst.WasDisposed);
         }
         }
 
 
-        Responder.Instances.Clear ();
+        View.Instances.Clear ();
 
 
         // Validate there are no outstanding Application.RunState-based instances 
         // Validate there are no outstanding Application.RunState-based instances 
         // after a scenario was selected to run. This proves the main UI Catalog
         // after a scenario was selected to run. This proves the main UI Catalog

+ 3 - 3
UnitTests/Application/ApplicationTests.cs

@@ -13,7 +13,7 @@ public class ApplicationTests
         ConfigurationManager.Locations = ConfigurationManager.ConfigLocations.None;
         ConfigurationManager.Locations = ConfigurationManager.ConfigLocations.None;
 
 
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Responder.Instances.Clear ();
+        View.Instances.Clear ();
         RunState.Instances.Clear ();
         RunState.Instances.Clear ();
 #endif
 #endif
     }
     }
@@ -66,7 +66,7 @@ public class ApplicationTests
         Assert.True (shutdown);
         Assert.True (shutdown);
 
 
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Assert.Empty (Responder.Instances);
+        Assert.Empty (View.Instances);
 #endif
 #endif
         lock (_timeoutLock)
         lock (_timeoutLock)
         {
         {
@@ -393,7 +393,7 @@ public class ApplicationTests
         // Validate there are no outstanding Responder-based instances 
         // Validate there are no outstanding Responder-based instances 
         // after a scenario was selected to run. This proves the main UI Catalog
         // after a scenario was selected to run. This proves the main UI Catalog
         // 'app' closed cleanly.
         // 'app' closed cleanly.
-        Assert.Empty (Responder.Instances);
+        Assert.Empty (View.Instances);
 #endif
 #endif
     }
     }
 
 

+ 2 - 2
UnitTests/Application/KeyboardTests.cs

@@ -11,7 +11,7 @@ public class KeyboardTests
     {
     {
         _output = output;
         _output = output;
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Responder.Instances.Clear ();
+        View.Instances.Clear ();
         RunState.Instances.Clear ();
         RunState.Instances.Clear ();
 #endif
 #endif
     }
     }
@@ -671,7 +671,7 @@ public class KeyboardTests
         Assert.True (shutdown);
         Assert.True (shutdown);
 
 
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Assert.Empty (Responder.Instances);
+        Assert.Empty (View.Instances);
 #endif
 #endif
         lock (_timeoutLock)
         lock (_timeoutLock)
         {
         {

+ 1 - 1
UnitTests/Application/Mouse/ApplicationMouseTests.cs

@@ -13,7 +13,7 @@ public class ApplicationMouseTests
     {
     {
         _output = output;
         _output = output;
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Responder.Instances.Clear ();
+        View.Instances.Clear ();
         RunState.Instances.Clear ();
         RunState.Instances.Clear ();
 #endif
 #endif
     }
     }

+ 1 - 1
UnitTests/Application/RunStateTests.cs

@@ -8,7 +8,7 @@ public class RunStateTests
     public RunStateTests ()
     public RunStateTests ()
     {
     {
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Responder.Instances.Clear ();
+        View.Instances.Clear ();
         RunState.Instances.Clear ();
         RunState.Instances.Clear ();
 #endif
 #endif
     }
     }

+ 1 - 180
UnitTests/Input/ResponderTests.cs

@@ -4,110 +4,7 @@ namespace Terminal.Gui.InputTests;
 
 
 public class ResponderTests
 public class ResponderTests
 {
 {
-    // Generic lifetime (IDisposable) tests
-    [Fact]
-    [TestRespondersDisposed]
-    public void Dispose_Works ()
-    {
-        var r = new Responder ();
-#if DEBUG_IDISPOSABLE
-        Assert.Single (Responder.Instances);
-#endif
-
-        r.Dispose ();
-#if DEBUG_IDISPOSABLE
-        Assert.Empty (Responder.Instances);
-#endif
-    }
-
-    [Fact]
-    public void Disposing_Event_Notify_All_Subscribers_On_The_First_Container ()
-    {
-    #if DEBUG_IDISPOSABLE
-        // Only clear before because need to test after assert
-        Responder.Instances.Clear ();
-    #endif
-
-        var container1 = new View { Id = "Container1" };
-        var count = 0;
-
-        var view = new View { Id = "View" };
-        view.Disposing += View_Disposing;
-        container1.Add (view);
-        Assert.Equal (container1, view.SuperView);
-
-        void View_Disposing (object sender, EventArgs e)
-        {
-            count++;
-            Assert.Equal (view, sender);
-            container1.Remove ((View)sender);
-        }
-
-        Assert.Single (container1.Subviews);
-
-        var container2 = new View { Id = "Container2" };
-
-        container2.Add (view);
-        Assert.Equal (container2, view.SuperView);
-        Assert.Equal (container1.Subviews.Count, container2.Subviews.Count);
-        container2.Dispose ();
-
-        Assert.Empty (container1.Subviews);
-        Assert.Empty (container2.Subviews);
-        Assert.Equal (1, count);
-        Assert.Null (view.SuperView);
-
-        container1.Dispose ();
-
-    #if DEBUG_IDISPOSABLE
-        Assert.Empty (Responder.Instances);
-    #endif
-    }
-
-    [Fact]
-    public void Disposing_Event_Notify_All_Subscribers_On_The_Second_Container ()
-    {
-    #if DEBUG_IDISPOSABLE
-        // Only clear before because need to test after assert
-        Responder.Instances.Clear ();
-    #endif
-
-        var container1 = new View { Id = "Container1" };
-
-        var view = new View { Id = "View" };
-        container1.Add (view);
-        Assert.Equal (container1, view.SuperView);
-        Assert.Single (container1.Subviews);
-
-        var container2 = new View { Id = "Container2" };
-        var count = 0;
-
-        view.Disposing += View_Disposing;
-        container2.Add (view);
-        Assert.Equal (container2, view.SuperView);
-
-        void View_Disposing (object sender, EventArgs e)
-        {
-            count++;
-            Assert.Equal (view, sender);
-            container2.Remove ((View)sender);
-        }
-
-        Assert.Equal (container1.Subviews.Count, container2.Subviews.Count);
-        container1.Dispose ();
-
-        Assert.Empty (container1.Subviews);
-        Assert.Empty (container2.Subviews);
-        Assert.Equal (1, count);
-        Assert.Null (view.SuperView);
-
-        container2.Dispose ();
-
-    #if DEBUG_IDISPOSABLE
-        Assert.Empty (Responder.Instances);
-    #endif
-    }
-
+   
 
 
     [Fact]
     [Fact]
     public void KeyPressed_Handled_True_Cancels_KeyPress ()
     public void KeyPressed_Handled_True_Cancels_KeyPress ()
@@ -125,82 +22,6 @@ public class ResponderTests
         r.Dispose ();
         r.Dispose ();
     }
     }
 
 
-    [Fact]
-    [TestRespondersDisposed]
-    public void New_Initializes ()
-    {
-        var r = new Responder ();
-        Assert.NotNull (r);
-        Assert.Equal ("Terminal.Gui.Responder", r.ToString ());
-        r.Dispose ();
-    }
-
-    [Fact]
-    [TestRespondersDisposed]
-    public void New_Methods_Return_False ()
-    {
-        var r = new View ();
-
-        //Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown }));
-        Assert.False (r.NewKeyDownEvent (new Key { KeyCode = KeyCode.Null }));
-        Assert.False (r.NewKeyDownEvent (new Key { KeyCode = KeyCode.Null }));
-        Assert.False (r.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.AllEvents }));
-
-        var v = new View ();
-        //Assert.False (r.OnEnter (v));
-        v.Dispose ();
-
-        v = new View ();
-        //Assert.False (r.OnLeave (v));
-        v.Dispose ();
-
-        r.Dispose ();
-    }
-
-    [Fact]
-    public void Responder_Not_Notifying_Dispose ()
-    {
-        // Only clear before because need to test after assert
-    #if DEBUG_IDISPOSABLE
-        Responder.Instances.Clear ();
-    #endif
-        var container1 = new View { Id = "Container1" };
-
-        var view = new View { Id = "View" };
-        container1.Add (view);
-        Assert.Equal (container1, view.SuperView);
-
-        Assert.Single (container1.Subviews);
-
-        var container2 = new View { Id = "Container2" };
-
-        container2.Add (view);
-        Assert.Equal (container2, view.SuperView);
-        Assert.Equal (container1.Subviews.Count, container2.Subviews.Count);
-        container1.Dispose ();
-
-        Assert.Empty (container1.Subviews);
-        Assert.NotEmpty (container2.Subviews);
-        Assert.Single (container2.Subviews);
-        Assert.Null (view.SuperView);
-
-        // Trying access disposed properties
-    #if DEBUG_IDISPOSABLE
-        Assert.True (container2.Subviews [0].WasDisposed);
-    #endif
-        Assert.False (container2.Subviews [0].CanFocus);
-        Assert.Null (container2.Subviews [0].Margin);
-        Assert.Null (container2.Subviews [0].Border);
-        Assert.Null (container2.Subviews [0].Padding);
-        Assert.Null (view.SuperView);
-
-        container2.Dispose ();
-
-    #if DEBUG_IDISPOSABLE
-        Assert.Empty (Responder.Instances);
-    #endif
-    }
-
     public class DerivedView : View
     public class DerivedView : View
     {
     {
         protected override bool OnKeyDown (Key keyEvent) { return true; }
         protected override bool OnKeyDown (Key keyEvent) { return true; }

+ 10 - 10
UnitTests/TestHelpers.cs

@@ -86,13 +86,13 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
 
 
                 Application.Shutdown ();
                 Application.Shutdown ();
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-                if (Responder.Instances.Count == 0)
+                if (View.Instances.Count == 0)
                 {
                 {
-                    Assert.Empty (Responder.Instances);
+                    Assert.Empty (View.Instances);
                 }
                 }
                 else
                 else
                 {
                 {
-                    Responder.Instances.Clear ();
+                    View.Instances.Clear ();
                 }
                 }
 #endif
 #endif
             }
             }
@@ -103,7 +103,7 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
             //finally
             //finally
             {
             {
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-                Responder.Instances.Clear ();
+                View.Instances.Clear ();
                 Application.ResetState (true);
                 Application.ResetState (true);
 #endif
 #endif
             }
             }
@@ -126,13 +126,13 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
 
 
             // Clear out any lingering Responder instances from previous tests
             // Clear out any lingering Responder instances from previous tests
-            if (Responder.Instances.Count == 0)
+            if (View.Instances.Count == 0)
             {
             {
-                Assert.Empty (Responder.Instances);
+                Assert.Empty (View.Instances);
             }
             }
             else
             else
             {
             {
-                Responder.Instances.Clear ();
+                View.Instances.Clear ();
             }
             }
 #endif
 #endif
             Application.Init ((ConsoleDriver)Activator.CreateInstance (_driverType));
             Application.Init ((ConsoleDriver)Activator.CreateInstance (_driverType));
@@ -160,7 +160,7 @@ public class TestRespondersDisposed : BeforeAfterTestAttribute
         base.After (methodUnderTest);
         base.After (methodUnderTest);
 
 
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Assert.Empty (Responder.Instances);
+        Assert.Empty (View.Instances);
 #endif
 #endif
     }
     }
 
 
@@ -172,8 +172,8 @@ public class TestRespondersDisposed : BeforeAfterTestAttribute
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
 
 
         // Clear out any lingering Responder instances from previous tests
         // Clear out any lingering Responder instances from previous tests
-        Responder.Instances.Clear ();
-        Assert.Empty (Responder.Instances);
+        View.Instances.Clear ();
+        Assert.Empty (View.Instances);
 #endif
 #endif
     }
     }
 }
 }

+ 3 - 3
UnitTests/UICatalog/ScenarioTests.cs

@@ -10,7 +10,7 @@ public class ScenarioTests : TestsAllViews
     public ScenarioTests (ITestOutputHelper output)
     public ScenarioTests (ITestOutputHelper output)
     {
     {
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Responder.Instances.Clear ();
+        View.Instances.Clear ();
 #endif
 #endif
         _output = output;
         _output = output;
     }
     }
@@ -68,7 +68,7 @@ public class ScenarioTests : TestsAllViews
         Assert.True (shutdown);
         Assert.True (shutdown);
 
 
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Assert.Empty (Responder.Instances);
+        Assert.Empty (View.Instances);
 #endif
 #endif
 
 
         lock (_timeoutLock)
         lock (_timeoutLock)
@@ -836,7 +836,7 @@ public class ScenarioTests : TestsAllViews
         ConfigurationManager.Reset ();
         ConfigurationManager.Reset ();
 
 
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Assert.Empty (Responder.Instances);
+        Assert.Empty (View.Instances);
 #endif
 #endif
     }
     }
 
 

+ 2 - 2
UnitTests/View/Layout/Dim.Tests.cs

@@ -470,8 +470,8 @@ public class DimTests
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
 
 
         // HACK: Force clean up of Responders to avoid having to Dispose all the Views created above.
         // HACK: Force clean up of Responders to avoid having to Dispose all the Views created above.
-        Responder.Instances.Clear ();
-        Assert.Empty (Responder.Instances);
+        View.Instances.Clear ();
+        Assert.Empty (View.Instances);
 #endif
 #endif
     }
     }
 
 

+ 1 - 1
UnitTests/View/Layout/Pos.ViewTests.cs

@@ -249,7 +249,7 @@ public class PosViewTests (ITestOutputHelper output)
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
 
 
         // HACK: Force clean up of Responders to avoid having to Dispose all the Views created above.
         // HACK: Force clean up of Responders to avoid having to Dispose all the Views created above.
-        Responder.Instances.Clear ();
+        View.Instances.Clear ();
 #endif
 #endif
     }
     }
 
 

+ 151 - 2
UnitTests/View/ViewTests.cs

@@ -6,6 +6,155 @@ namespace Terminal.Gui.ViewTests;
 
 
 public class ViewTests (ITestOutputHelper output)
 public class ViewTests (ITestOutputHelper output)
 {
 {
+    // Generic lifetime (IDisposable) tests
+    [Fact]
+    [TestRespondersDisposed]
+    public void Dispose_Works ()
+    {
+        var r = new View ();
+#if DEBUG_IDISPOSABLE
+        Assert.Single (View.Instances);
+#endif
+
+        r.Dispose ();
+#if DEBUG_IDISPOSABLE
+        Assert.Empty (View.Instances);
+#endif
+    }
+
+    [Fact]
+    public void Disposing_Event_Notify_All_Subscribers_On_The_First_Container ()
+    {
+#if DEBUG_IDISPOSABLE
+        // Only clear before because need to test after assert
+        View.Instances.Clear ();
+#endif
+
+        var container1 = new View { Id = "Container1" };
+        var count = 0;
+
+        var view = new View { Id = "View" };
+        view.Disposing += View_Disposing;
+        container1.Add (view);
+        Assert.Equal (container1, view.SuperView);
+
+        void View_Disposing (object sender, EventArgs e)
+        {
+            count++;
+            Assert.Equal (view, sender);
+            container1.Remove ((View)sender);
+        }
+
+        Assert.Single (container1.Subviews);
+
+        var container2 = new View { Id = "Container2" };
+
+        container2.Add (view);
+        Assert.Equal (container2, view.SuperView);
+        Assert.Equal (container1.Subviews.Count, container2.Subviews.Count);
+        container2.Dispose ();
+
+        Assert.Empty (container1.Subviews);
+        Assert.Empty (container2.Subviews);
+        Assert.Equal (1, count);
+        Assert.Null (view.SuperView);
+
+        container1.Dispose ();
+
+#if DEBUG_IDISPOSABLE
+        Assert.Empty (View.Instances);
+#endif
+    }
+
+    [Fact]
+    public void Disposing_Event_Notify_All_Subscribers_On_The_Second_Container ()
+    {
+#if DEBUG_IDISPOSABLE
+        // Only clear before because need to test after assert
+        View.Instances.Clear ();
+#endif
+
+        var container1 = new View { Id = "Container1" };
+
+        var view = new View { Id = "View" };
+        container1.Add (view);
+        Assert.Equal (container1, view.SuperView);
+        Assert.Single (container1.Subviews);
+
+        var container2 = new View { Id = "Container2" };
+        var count = 0;
+
+        view.Disposing += View_Disposing;
+        container2.Add (view);
+        Assert.Equal (container2, view.SuperView);
+
+        void View_Disposing (object sender, EventArgs e)
+        {
+            count++;
+            Assert.Equal (view, sender);
+            container2.Remove ((View)sender);
+        }
+
+        Assert.Equal (container1.Subviews.Count, container2.Subviews.Count);
+        container1.Dispose ();
+
+        Assert.Empty (container1.Subviews);
+        Assert.Empty (container2.Subviews);
+        Assert.Equal (1, count);
+        Assert.Null (view.SuperView);
+
+        container2.Dispose ();
+
+#if DEBUG_IDISPOSABLE
+        Assert.Empty (View.Instances);
+#endif
+    }
+
+
+    [Fact]
+    public void Not_Notifying_Dispose ()
+    {
+        // Only clear before because need to test after assert
+#if DEBUG_IDISPOSABLE
+        View.Instances.Clear ();
+#endif
+        var container1 = new View { Id = "Container1" };
+
+        var view = new View { Id = "View" };
+        container1.Add (view);
+        Assert.Equal (container1, view.SuperView);
+
+        Assert.Single (container1.Subviews);
+
+        var container2 = new View { Id = "Container2" };
+
+        container2.Add (view);
+        Assert.Equal (container2, view.SuperView);
+        Assert.Equal (container1.Subviews.Count, container2.Subviews.Count);
+        container1.Dispose ();
+
+        Assert.Empty (container1.Subviews);
+        Assert.NotEmpty (container2.Subviews);
+        Assert.Single (container2.Subviews);
+        Assert.Null (view.SuperView);
+
+        // Trying access disposed properties
+#if DEBUG_IDISPOSABLE
+        Assert.True (container2.Subviews [0].WasDisposed);
+#endif
+        Assert.False (container2.Subviews [0].CanFocus);
+        Assert.Null (container2.Subviews [0].Margin);
+        Assert.Null (container2.Subviews [0].Border);
+        Assert.Null (container2.Subviews [0].Padding);
+        Assert.Null (view.SuperView);
+
+        container2.Dispose ();
+
+#if DEBUG_IDISPOSABLE
+        Assert.Empty (View.Instances);
+#endif
+    }
+
     [Fact]
     [Fact]
     [AutoInitShutdown]
     [AutoInitShutdown]
     public void Clear_Viewport_Can_Use_Driver_AddRune_Or_AddStr_Methods ()
     public void Clear_Viewport_Can_Use_Driver_AddRune_Or_AddStr_Methods ()
@@ -428,7 +577,7 @@ At 0,0
         Assert.NotNull (view.Padding);
         Assert.NotNull (view.Padding);
 
 
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Assert.Equal (4, Responder.Instances.Count);
+        Assert.Equal (4, View.Instances.Count);
 #endif
 #endif
 
 
         view.Dispose ();
         view.Dispose ();
@@ -948,7 +1097,7 @@ At 0,0
         super.Dispose ();
         super.Dispose ();
 
 
 #if DEBUG_IDISPOSABLE
 #if DEBUG_IDISPOSABLE
-        Assert.Empty (Responder.Instances);
+        Assert.Empty (View.Instances);
 #endif
 #endif
 
 
         // Default Constructor
         // Default Constructor