Index: Core/Common/src/Core.Common.Gui/Forms/PropertyGridView/PropertyGridView.cs =================================================================== diff -u -rb2b9fdf365e70928a05c57966eeed30d9050e528 -rf51ba688e19c7ee65cff9836fb221eef60b52c75 --- Core/Common/src/Core.Common.Gui/Forms/PropertyGridView/PropertyGridView.cs (.../PropertyGridView.cs) (revision b2b9fdf365e70928a05c57966eeed30d9050e528) +++ Core/Common/src/Core.Common.Gui/Forms/PropertyGridView/PropertyGridView.cs (.../PropertyGridView.cs) (revision f51ba688e19c7ee65cff9836fb221eef60b52c75) @@ -38,9 +38,7 @@ public class PropertyGridView : PropertyGrid, IView, IObserver { private readonly IPropertyResolver propertyResolver; - private object data; - private IObservable observable; /// @@ -79,6 +77,9 @@ } else { + DetachObservable(); + AttachObservable(); + Refresh(); } } @@ -96,10 +97,7 @@ protected override void Dispose(bool disposing) { - if (observable != null) - { - observable.Detach(this); - } + observable?.Detach(this); base.Dispose(disposing); } @@ -120,29 +118,32 @@ return; } - if (observable != null) - { - observable.Detach(this); - observable = null; - } + DetachObservable(); data = value; - SelectedObject = GetObjectProperties(value); + AttachObservable(); + } + } - var dynamicPropertyBag = SelectedObject as DynamicPropertyBag; - if (dynamicPropertyBag != null) - { - var objectProperties = dynamicPropertyBag.WrappedObject as IObjectProperties; - if (objectProperties != null) - { - observable = objectProperties.Data as IObservable; + private void DetachObservable() + { + if (observable != null) + { + observable.Detach(this); + observable = null; + } + } - if (observable != null) - { - observable.Attach(this); - } - } - } + private void AttachObservable() + { + SelectedObject = GetObjectProperties(data); + + var dynamicPropertyBag = SelectedObject as DynamicPropertyBag; + var objectProperties = dynamicPropertyBag?.WrappedObject as IObjectProperties; + if (objectProperties != null) + { + observable = objectProperties.Data as IObservable; + observable?.Attach(this); } } Index: Core/Common/test/Core.Common.Gui.Test/Forms/PropertyGridView/PropertyGridViewTest.cs =================================================================== diff -u -r53f640e7100d9527310acb18280120658f4b2182 -rf51ba688e19c7ee65cff9836fb221eef60b52c75 --- Core/Common/test/Core.Common.Gui.Test/Forms/PropertyGridView/PropertyGridViewTest.cs (.../PropertyGridViewTest.cs) (revision 53f640e7100d9527310acb18280120658f4b2182) +++ Core/Common/test/Core.Common.Gui.Test/Forms/PropertyGridView/PropertyGridViewTest.cs (.../PropertyGridViewTest.cs) (revision f51ba688e19c7ee65cff9836fb221eef60b52c75) @@ -20,10 +20,12 @@ // All rights reserved. using System; +using System.Linq; using System.Windows.Forms; using Core.Common.Base; using Core.Common.Controls.Views; using Core.Common.Gui.Forms.PropertyGridView; +using Core.Common.Gui.PropertyBag; using NUnit.Framework; using Rhino.Mocks; @@ -58,33 +60,160 @@ Assert.IsInstanceOf(propertyGridView); Assert.IsInstanceOf(propertyGridView); Assert.IsNull(propertyGridView.Data); + Assert.AreEqual(PropertySort.Categorized, propertyGridView.PropertySort); + + ToolStrip toolStrip = propertyGridView.Controls.OfType().First(); + Assert.AreEqual("Gecategoriseerd", toolStrip.Items[0].ToolTipText); + Assert.AreEqual("Alfabetisch", toolStrip.Items[1].ToolTipText); } mockRepository.VerifyAll(); } [Test] - public void Data_SetSameDataObject_NoRedundantViewUpdate() + public void Show_ValidParameter_ExpectedProperties() { // Setup var mockRepository = new MockRepository(); var propertyResolverStub = mockRepository.Stub(); mockRepository.ReplayAll(); + using (var form = new Form()) + using (var propertyGridView = new Gui.Forms.PropertyGridView.PropertyGridView(propertyResolverStub)) + { + form.Controls.Add(propertyGridView); + + // Call + form.Show(); + + // Assert + ToolStrip toolStrip = propertyGridView.Controls.OfType().First(); + Assert.AreEqual(5, toolStrip.Items.Count); + Assert.IsTrue(toolStrip.Items[0].Visible); + Assert.IsTrue(toolStrip.Items[1].Visible); + Assert.IsFalse(toolStrip.Items[2].Visible); + Assert.IsFalse(toolStrip.Items[3].Visible); + Assert.IsFalse(toolStrip.Items[4].Visible); + } + mockRepository.VerifyAll(); + } + + [Test] + public void Data_SetNull_UpdateView() + { + // Setup var dataObject = new object(); - using (var propertyGridView = new Gui.Forms.PropertyGridView.PropertyGridView(propertyResolverStub)) + var mockRepository = new MockRepository(); + var propertyResolverStub = mockRepository.StrictMock(); + propertyResolverStub.Expect(prs => prs.GetObjectProperties(dataObject)).Return(null); + propertyResolverStub.Expect(prs => prs.GetObjectProperties(null)).Return(null); + mockRepository.ReplayAll(); + + using (var propertyGridView = new TestGuiPropertyGridView(propertyResolverStub)) { propertyGridView.Data = dataObject; var selectedObject = propertyGridView.SelectedObject; // Call + propertyGridView.Data = null; + + // Assert + Assert.AreSame(selectedObject, propertyGridView.SelectedObject); + Assert.AreEqual(0, propertyGridView.RefreshCalled); + } + mockRepository.VerifyAll(); + } + + [Test] + public void Data_SetSameDataObject_NoRedundantViewUpdate() + { + // Setup + var dataObject = new object(); + + var mockRepository = new MockRepository(); + var propertyResolverStub = mockRepository.StrictMock(); + propertyResolverStub.Expect(prs => prs.GetObjectProperties(dataObject)).Return(null); + mockRepository.ReplayAll(); + + using (var propertyGridView = new TestGuiPropertyGridView(propertyResolverStub)) + { propertyGridView.Data = dataObject; + var selectedObject = propertyGridView.SelectedObject; + + // Call + propertyGridView.Data = dataObject; + // Assert Assert.AreSame(selectedObject, propertyGridView.SelectedObject); + Assert.AreEqual(0, propertyGridView.RefreshCalled); } mockRepository.VerifyAll(); } + + [Test] + public void GivenPropertyGridViewWithObservableSet_WhenNotifyObserverCalled_ThenRefreshTriggered() + { + // Given + var dataObject = new object(); + var observerable = new SimpleObservable(); + + var mockRepository = new MockRepository(); + var objectProperties = mockRepository.Stub(); + objectProperties.Data = observerable; + + var propertyResolverStub = mockRepository.StrictMock(); + propertyResolverStub.Expect(prs => prs.GetObjectProperties(dataObject)).Return(new DynamicPropertyBag(objectProperties)).Repeat.Twice(); + mockRepository.ReplayAll(); + + using (var propertyGridView = new TestGuiPropertyGridView(propertyResolverStub)) + { + // When + propertyGridView.Data = dataObject; + + // Then + observerable.NotifyObservers(); + Assert.AreEqual(1, propertyGridView.RefreshCalled); + } + mockRepository.VerifyAll(); + } + + [Test] + public void Dispose_AlreadyDisposed_DoesNotThrowException() + { + // Setup + var mockRepository = new MockRepository(); + var propertyResolverStub = mockRepository.Stub(); + mockRepository.ReplayAll(); + + // Call + TestDelegate call = () => + { + using (var control = new Gui.Forms.PropertyGridView.PropertyGridView(propertyResolverStub)) + { + control.Dispose(); + } + }; + + // Assert + Assert.DoesNotThrow(call); + mockRepository.VerifyAll(); + } + + private class TestGuiPropertyGridView : Gui.Forms.PropertyGridView.PropertyGridView + { + public TestGuiPropertyGridView(IPropertyResolver propertyResolver) : base(propertyResolver) {} + + public int RefreshCalled { get; private set; } + + public override void Refresh() + { + RefreshCalled++; + base.Refresh(); + } + } + + private class SimpleObservable : Observable {} } } \ No newline at end of file Index: Core/Components/src/Core.Components.DotSpatial.Forms/MapControl.cs =================================================================== diff -u -r46997e65ad8ad93701ea46c519d8c75e2b6cc0c0 -rf51ba688e19c7ee65cff9836fb221eef60b52c75 --- Core/Components/src/Core.Components.DotSpatial.Forms/MapControl.cs (.../MapControl.cs) (revision 46997e65ad8ad93701ea46c519d8c75e2b6cc0c0) +++ Core/Components/src/Core.Components.DotSpatial.Forms/MapControl.cs (.../MapControl.cs) (revision f51ba688e19c7ee65cff9836fb221eef60b52c75) @@ -202,6 +202,8 @@ if (!ReferenceEquals(backgroundMapData, backgroundMapDataContainer.MapData)) { backgroundMapData = (WmtsMapData) backgroundMapDataContainer.MapData; + backGroundMapDataObserver.Observable = backgroundMapData; + if (backgroundMapData != null) { HandleBackgroundMapDataChange(); Index: Core/Components/test/Core.Components.DotSpatial.Forms.Test/MapControlTest.cs =================================================================== diff -u -r3a1d4488d68236efe6eccbd60be3484735aa689b -rf51ba688e19c7ee65cff9836fb221eef60b52c75 --- Core/Components/test/Core.Components.DotSpatial.Forms.Test/MapControlTest.cs (.../MapControlTest.cs) (revision 3a1d4488d68236efe6eccbd60be3484735aa689b) +++ Core/Components/test/Core.Components.DotSpatial.Forms.Test/MapControlTest.cs (.../MapControlTest.cs) (revision f51ba688e19c7ee65cff9836fb221eef60b52c75) @@ -1292,6 +1292,51 @@ } [Test] + [TestCase(false, 0)] + [TestCase(true, 1)] + public void GivenMapControlWithDataDifferentMapDataSet_WhenNotified_LayerVisibilityAsExpected(bool newMapDataNotify, int layerVisibilityChanged) + { + // Given + var actualLayerVisibilityChanged = 0; + WmtsMapData backgroundMapData = WmtsMapData.CreateDefaultPdokMapData(); + WmtsMapData differentBackgroundMapData = WmtsMapData.CreateDefaultPdokMapData(); + var mapDataContainer = new BackgroundMapDataContainer + { + MapData = backgroundMapData + }; + + using (new UseCustomTileSourceFactoryConfig(backgroundMapData)) + using (new UseCustomTileSourceFactoryConfig(differentBackgroundMapData)) + using (var map = new MapControl()) + { + map.BackgroundMapData = mapDataContainer; + mapDataContainer.IsVisible = false; + + mapDataContainer.MapData = differentBackgroundMapData; + mapDataContainer.NotifyObservers(); + + IMapLayerCollection layers = map.Controls.OfType().First().Layers; + layers.LayerVisibleChanged += (sender, args) => { actualLayerVisibilityChanged++; }; + + differentBackgroundMapData.IsVisible = true; + backgroundMapData.IsVisible = true; + + // When + if (newMapDataNotify) + { + differentBackgroundMapData.NotifyObservers(); + } + else + { + backgroundMapData.NotifyObservers(); + } + + // Then + Assert.AreEqual(layerVisibilityChanged, actualLayerVisibilityChanged); + } + } + + [Test] public void GivenMapControlWithDataAndBackground_WhenDifferentBackgroundMapDataSet_LayersReprojected() { // Given Index: Ringtoets/Integration/src/Ringtoets.Integration.Forms/PropertyClasses/BackgroundWmtsMapDataContainerProperties.cs =================================================================== diff -u -r9c1789fd6fa33b6ea18339bf2474102471ef4510 -rf51ba688e19c7ee65cff9836fb221eef60b52c75 --- Ringtoets/Integration/src/Ringtoets.Integration.Forms/PropertyClasses/BackgroundWmtsMapDataContainerProperties.cs (.../BackgroundWmtsMapDataContainerProperties.cs) (revision 9c1789fd6fa33b6ea18339bf2474102471ef4510) +++ Ringtoets/Integration/src/Ringtoets.Integration.Forms/PropertyClasses/BackgroundWmtsMapDataContainerProperties.cs (.../BackgroundWmtsMapDataContainerProperties.cs) (revision f51ba688e19c7ee65cff9836fb221eef60b52c75) @@ -55,7 +55,7 @@ /// object. /// /// The data to be used. - /// if it's valid. + /// if it is valid. /// Thrown when /// is not suitable for this object. /// Thrown when