From d3a603de38fc011578ef7d1fe035a7fffe7afc96 Mon Sep 17 00:00:00 2001 From: Laurent Bugnion Date: Sun, 17 Jan 2016 21:18:56 +0100 Subject: [PATCH] Issue 7701: RaisePC public ? NOTE: This can be a breaking change if you were overriding RaisePropertyChanged in your code before. Issue 7564: The RaisePropertyChanged Overloads Contain Duplicate Code. This is solved now in ViewModelBase and ObservableObject. All calls are routed through ObservableObject.RaisePropertyChanged(string). If you override this method only in your VMs, it will always be called if you call any of the Set methods, RaisePropertyChanged(string) or RaisePropertyChanged(Expression). --- .../ObservableObject.cs | 20 +- .../GalaSoft.MvvmLight (PCL)/ViewModelBase.cs | 24 +- ...laSoft.MvvmLight.Platform (Android).csproj | 2 +- .../GalaSoft.MvvmLight.Test (NET35).csproj | 12 + .../GalaSoft.MvvmLight.Test (NET4).csproj | 12 + .../GalaSoft.MvvmLight.Test (SL5).csproj | 9 + .../GalaSoft.MvvmLight.Test (PNET45).csproj | 4 + .../ObservableObjectTest.cs | 105 ++++++++ .../ViewModel/TestObservableObject.cs | 104 ++++++++ .../ViewModel/TestViewModel.cs | 1 + .../TestViewModelForPropertyChanged.cs | 179 +++++++++++++ .../ViewModelBaseAndPropertyChangedTest.cs | 249 ++++++++++++++++++ .../GalaSoft.MvvmLight.Test (PWIN81).csproj | 12 + .../GalaSoft.MvvmLight.Test (PWP81).csproj | 12 + .../GalaSoft.MvvmLight.Test (PWPSL80).csproj | 12 + .../GalaSoft.MvvmLight.Test (PWPSL81).csproj | 13 +- 16 files changed, 743 insertions(+), 27 deletions(-) create mode 100644 GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ObservableObjectTest.cs create mode 100644 GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestObservableObject.cs create mode 100644 GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestViewModelForPropertyChanged.cs create mode 100644 GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModelBaseAndPropertyChangedTest.cs diff --git a/GalaSoft.MvvmLight/GalaSoft.MvvmLight (PCL)/ObservableObject.cs b/GalaSoft.MvvmLight/GalaSoft.MvvmLight (PCL)/ObservableObject.cs index df5e4d0..8b8fe2c 100644 --- a/GalaSoft.MvvmLight/GalaSoft.MvvmLight (PCL)/ObservableObject.cs +++ b/GalaSoft.MvvmLight/GalaSoft.MvvmLight (PCL)/ObservableObject.cs @@ -129,7 +129,7 @@ namespace GalaSoft.MvvmLight "Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "This cannot be an event")] - protected virtual void RaisePropertyChanging( + public virtual void RaisePropertyChanging( [CallerMemberName] string propertyName = null) #else /// @@ -144,7 +144,7 @@ namespace GalaSoft.MvvmLight "Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "This cannot be an event")] - protected virtual void RaisePropertyChanging( + public virtual void RaisePropertyChanging( string propertyName) #endif { @@ -171,7 +171,7 @@ namespace GalaSoft.MvvmLight "Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "This cannot be an event")] - protected virtual void RaisePropertyChanged( + public virtual void RaisePropertyChanged( [CallerMemberName] string propertyName = null) #else /// @@ -186,7 +186,7 @@ namespace GalaSoft.MvvmLight "Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "This cannot be an event")] - protected virtual void RaisePropertyChanged( + public virtual void RaisePropertyChanged( string propertyName) #endif { @@ -215,7 +215,7 @@ namespace GalaSoft.MvvmLight "Microsoft.Design", "CA1006:GenericMethodsShouldProvideTypeParameter", Justification = "This syntax is more convenient than other alternatives.")] - protected virtual void RaisePropertyChanging(Expression> propertyExpression) + public virtual void RaisePropertyChanging(Expression> propertyExpression) { var handler = PropertyChanging; if (handler != null) @@ -241,13 +241,19 @@ namespace GalaSoft.MvvmLight "Microsoft.Design", "CA1006:GenericMethodsShouldProvideTypeParameter", Justification = "This syntax is more convenient than other alternatives.")] - protected virtual void RaisePropertyChanged(Expression> propertyExpression) + public virtual void RaisePropertyChanged(Expression> propertyExpression) { var handler = PropertyChanged; + if (handler != null) { var propertyName = GetPropertyName(propertyExpression); - handler(this, new PropertyChangedEventArgs(propertyName)); + + if (!string.IsNullOrEmpty(propertyName)) + { + // ReSharper disable once ExplicitCallerInfoArgument + RaisePropertyChanged(propertyName); + } } } diff --git a/GalaSoft.MvvmLight/GalaSoft.MvvmLight (PCL)/ViewModelBase.cs b/GalaSoft.MvvmLight/GalaSoft.MvvmLight (PCL)/ViewModelBase.cs index 3218e10..169a71d 100644 --- a/GalaSoft.MvvmLight/GalaSoft.MvvmLight (PCL)/ViewModelBase.cs +++ b/GalaSoft.MvvmLight/GalaSoft.MvvmLight (PCL)/ViewModelBase.cs @@ -122,7 +122,6 @@ namespace GalaSoft.MvvmLight #elif NETFX_CORE _isInDesignMode = DesignMode.DesignModeEnabled; #elif XAMARIN - // TODO XAMARIN Is there such a thing as design mode? How to detect it? _isInDesignMode = false; #else var prop = DesignerProperties.IsInDesignModeProperty; @@ -169,8 +168,6 @@ namespace GalaSoft.MvvmLight return false; } - - private static bool IsInDesignModeSilverlight() { try @@ -368,7 +365,7 @@ namespace GalaSoft.MvvmLight SuppressMessage( "Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "This cannot be an event")] - protected virtual void RaisePropertyChanged( + public virtual void RaisePropertyChanged( #if CMNATTR [CallerMemberName] string propertyName = null, #else @@ -416,24 +413,15 @@ namespace GalaSoft.MvvmLight "Microsoft.Design", "CA1006:GenericMethodsShouldProvideTypeParameter", Justification = "This syntax is more convenient than the alternatives.")] - protected virtual void RaisePropertyChanged(Expression> propertyExpression, T oldValue, T newValue, bool broadcast) + public virtual void RaisePropertyChanged(Expression> propertyExpression, T oldValue, T newValue, bool broadcast) { - var handler = PropertyChangedHandler; + RaisePropertyChanged(propertyExpression); - if (handler != null - || broadcast) + if (broadcast) { + // Unfortunately I don't see a reliable way to not call GetPropertyName twice. var propertyName = GetPropertyName(propertyExpression); - - if (handler != null) - { - handler(this, new PropertyChangedEventArgs(propertyName)); - } - - if (broadcast) - { - Broadcast(oldValue, newValue, propertyName); - } + Broadcast(oldValue, newValue, propertyName); } } diff --git a/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/GalaSoft.MvvmLight.Platform (Android).csproj b/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/GalaSoft.MvvmLight.Platform (Android).csproj index b151ee5..9f72772 100644 --- a/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/GalaSoft.MvvmLight.Platform (Android).csproj +++ b/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/GalaSoft.MvvmLight.Platform (Android).csproj @@ -15,7 +15,7 @@ Resources\Resource.Designer.cs Off True - v5.1 + v6.0 true diff --git a/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (NET35)/GalaSoft.MvvmLight.Test (NET35).csproj b/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (NET35)/GalaSoft.MvvmLight.Test (NET35).csproj index 8c40e85..9867e99 100644 --- a/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (NET35)/GalaSoft.MvvmLight.Test (NET35).csproj +++ b/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (NET35)/GalaSoft.MvvmLight.Test (NET35).csproj @@ -230,6 +230,9 @@ ObservableObjectPropertyChangedTest.cs + + ObservableObjectTest.cs + Properties\AssemblyInfo.cs @@ -275,15 +278,24 @@ Threading\DispatcherHelperTest.cs + + ViewModelBaseAndPropertyChangedTest.cs + ViewModelBaseTest.cs ViewModel\TestClassWithObservableObject.cs + + ViewModel\TestObservableObject.cs + ViewModel\TestViewModel.cs + + ViewModel\TestViewModelForPropertyChanged.cs + ViewModel\TestViewModelNoMagicString.cs diff --git a/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (NET4)/GalaSoft.MvvmLight.Test (NET4).csproj b/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (NET4)/GalaSoft.MvvmLight.Test (NET4).csproj index 2c43085..319a364 100644 --- a/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (NET4)/GalaSoft.MvvmLight.Test (NET4).csproj +++ b/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (NET4)/GalaSoft.MvvmLight.Test (NET4).csproj @@ -221,6 +221,9 @@ ObservableObjectPropertyChangedTest.cs + + ObservableObjectTest.cs + Properties\AssemblyInfo.cs @@ -266,15 +269,24 @@ Threading\DispatcherHelperTest.cs + + ViewModelBaseAndPropertyChangedTest.cs + ViewModelBaseTest.cs ViewModel\TestClassWithObservableObject.cs + + ViewModel\TestObservableObject.cs + ViewModel\TestViewModel.cs + + ViewModel\TestViewModelForPropertyChanged.cs + ViewModel\TestViewModelNoMagicString.cs diff --git a/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (SL5)/GalaSoft.MvvmLight.Test (SL5).csproj b/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (SL5)/GalaSoft.MvvmLight.Test (SL5).csproj index 7426ba0..8a4c0ed 100644 --- a/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (SL5)/GalaSoft.MvvmLight.Test (SL5).csproj +++ b/GalaSoft.MvvmLight/Tests/GalaSoft.MvvmLight.Test (SL5)/GalaSoft.MvvmLight.Test (SL5).csproj @@ -95,9 +95,18 @@ + + ObservableObjectTest.cs + Stubs\TestClass1.cs + + ViewModels\TestObservableObject.cs + + + ViewModels\TestViewModelForPropertyChanged.cs + Command\EventArgsConverter.cs diff --git a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/GalaSoft.MvvmLight.Test (PNET45).csproj b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/GalaSoft.MvvmLight.Test (PNET45).csproj index 6a288c2..d7562ee 100644 --- a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/GalaSoft.MvvmLight.Test (PNET45).csproj +++ b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/GalaSoft.MvvmLight.Test (PNET45).csproj @@ -112,6 +112,7 @@ + @@ -127,9 +128,12 @@ + + + diff --git a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ObservableObjectTest.cs b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ObservableObjectTest.cs new file mode 100644 index 0000000..e13c758 --- /dev/null +++ b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ObservableObjectTest.cs @@ -0,0 +1,105 @@ +using System.Diagnostics.CodeAnalysis; +using GalaSoft.MvvmLight.Messaging; +using GalaSoft.MvvmLight.Test.ViewModel; + +#if NETFX_CORE || (WINDOWS_PHONE && !WINDOWS_PHONE7) +using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; +#else +using Microsoft.VisualStudio.TestTools.UnitTesting; +#endif + +namespace GalaSoft.MvvmLight.Test +{ + [TestClass] + [SuppressMessage("ReSharper", "InconsistentNaming")] + public class ObservableObjectTest + { + [TestMethod] + public void RaisePropertyChanged_WithString_ShouldCallRaisePropertyChangedWithStringOnly() + { + var testObject = new TestObservableObject(); + + var eventWasRaised = false; + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithString") + { + eventWasRaised = true; + } + }; + + Assert.IsFalse(testObject.BoolPropertyWithString); + testObject.BoolPropertyWithString = true; + Assert.IsTrue(testObject.BoolPropertyWithString); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsFalse(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + + [TestMethod] + public void RaisePropertyChanged_WithExpression_ShouldCallRaisePropertyChangedWithStringAndWithExpression() + { + var testObject = new TestObservableObject(); + + var eventWasRaised = false; + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithExpression") + { + eventWasRaised = true; + } + }; + + Assert.IsFalse(testObject.BoolPropertyWithExpression); + testObject.BoolPropertyWithExpression = true; + Assert.IsTrue(testObject.BoolPropertyWithExpression); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsTrue(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + + [TestMethod] + public void RaisePropertyChanged_WithSetAndExpression_ShouldCallRaisePropertyChangedWithStringAndWithExpression() + { + var testObject = new TestObservableObject(); + + var eventWasRaised = false; + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithSetAndExpression") + { + eventWasRaised = true; + } + }; + + Assert.IsFalse(testObject.BoolPropertyWithSetAndExpression); + testObject.BoolPropertyWithSetAndExpression = true; + Assert.IsTrue(testObject.BoolPropertyWithSetAndExpression); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsTrue(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + + [TestMethod] + public void RaisePropertyChanged_WithSetAndString_ShouldCallRaisePropertyChangedWithStringOnly() + { + var testObject = new TestObservableObject(); + + var eventWasRaised = false; + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithSetAndString") + { + eventWasRaised = true; + } + }; + + Assert.IsFalse(testObject.BoolPropertyWithSetAndString); + testObject.BoolPropertyWithSetAndString = true; + Assert.IsTrue(testObject.BoolPropertyWithSetAndString); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsFalse(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + } +} diff --git a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestObservableObject.cs b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestObservableObject.cs new file mode 100644 index 0000000..0fe854f --- /dev/null +++ b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestObservableObject.cs @@ -0,0 +1,104 @@ +using System; +using System.Linq.Expressions; + +namespace GalaSoft.MvvmLight.Test.ViewModel +{ + public class TestObservableObject : ObservableObject + { + public bool RaisePropertyChangedWithExpressionWasCalled + { + get; + private set; + } + + public bool RaisePropertyChangedWithPropertyNameWasCalled + { + get; + private set; + } + + public override void RaisePropertyChanged(string propertyName = null) + { + // ReSharper disable once ExplicitCallerInfoArgument + base.RaisePropertyChanged(propertyName); + RaisePropertyChangedWithPropertyNameWasCalled = true; + } + + public override void RaisePropertyChanged(Expression> propertyExpression) + { + base.RaisePropertyChanged(propertyExpression); + RaisePropertyChangedWithExpressionWasCalled = true; + } + + private bool _boolPropertyWithString; + + public bool BoolPropertyWithString + { + get + { + return _boolPropertyWithString; + } + + set + { + if (_boolPropertyWithString == value) + { + return; + } + + _boolPropertyWithString = value; + RaisePropertyChanged("BoolPropertyWithString"); + } + } + + private bool _boolPropertyWithExpression; + + public bool BoolPropertyWithExpression + { + get + { + return _boolPropertyWithExpression; + } + + set + { + if (_boolPropertyWithExpression == value) + { + return; + } + + _boolPropertyWithExpression = value; + RaisePropertyChanged(() => BoolPropertyWithExpression); + } + } + + private bool _boolPropertyWithSetAndString; + + public bool BoolPropertyWithSetAndString + { + get + { + return _boolPropertyWithSetAndString; + } + set + { + Set("BoolPropertyWithSetAndString", ref _boolPropertyWithSetAndString, value); + } + } + + + private bool _boolPropertyWithSetAndExpression; + + public bool BoolPropertyWithSetAndExpression + { + get + { + return _boolPropertyWithSetAndExpression; + } + set + { + Set(() => BoolPropertyWithSetAndExpression, ref _boolPropertyWithSetAndExpression, value); + } + } + } +} \ No newline at end of file diff --git a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestViewModel.cs b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestViewModel.cs index 3fdd0f6..ecc7483 100644 --- a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestViewModel.cs +++ b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using GalaSoft.MvvmLight.Messaging; namespace GalaSoft.MvvmLight.Test.ViewModel diff --git a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestViewModelForPropertyChanged.cs b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestViewModelForPropertyChanged.cs new file mode 100644 index 0000000..32b95d7 --- /dev/null +++ b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModel/TestViewModelForPropertyChanged.cs @@ -0,0 +1,179 @@ +using System; +using System.Linq.Expressions; + +namespace GalaSoft.MvvmLight.Test.ViewModel +{ + public class TestViewModelForPropertyChanged : ViewModelBase + { + public bool RaisePropertyChangedWithExpressionWasCalled + { + get; + private set; + } + + public bool RaisePropertyChangedWithPropertyNameWasCalled + { + get; + private set; + } + + public override void RaisePropertyChanged(string propertyName = null) + { + // ReSharper disable once ExplicitCallerInfoArgument + base.RaisePropertyChanged(propertyName); + RaisePropertyChangedWithPropertyNameWasCalled = true; + } + + public override void RaisePropertyChanged(Expression> propertyExpression) + { + base.RaisePropertyChanged(propertyExpression); + RaisePropertyChangedWithExpressionWasCalled = true; + } + + private bool _boolPropertyWithString; + + public bool BoolPropertyWithString + { + get + { + return _boolPropertyWithString; + } + + set + { + if (_boolPropertyWithString == value) + { + return; + } + + _boolPropertyWithString = value; + RaisePropertyChanged("BoolPropertyWithString"); + } + } + + private bool _boolPropertyWithExpression; + + public bool BoolPropertyWithExpression + { + get + { + return _boolPropertyWithExpression; + } + + set + { + if (_boolPropertyWithExpression == value) + { + return; + } + + _boolPropertyWithExpression = value; + RaisePropertyChanged(() => BoolPropertyWithExpression); + } + } + + private bool _boolPropertyWithExpressionAndMessage; + + public bool BoolPropertyWithExpressionAndMessage + { + get + { + return _boolPropertyWithExpressionAndMessage; + } + + set + { + if (_boolPropertyWithExpressionAndMessage == value) + { + return; + } + + var oldValue = _boolPropertyWithExpressionAndMessage; + _boolPropertyWithExpressionAndMessage = value; + RaisePropertyChanged(() => BoolPropertyWithExpressionAndMessage, oldValue, value, true); + } + } + + + private bool _boolPropertyWithStringAndMessage; + + public bool BoolPropertyWithStringAndMessage + { + get + { + return _boolPropertyWithStringAndMessage; + } + + set + { + if (_boolPropertyWithStringAndMessage == value) + { + return; + } + + var oldValue = _boolPropertyWithStringAndMessage; + _boolPropertyWithStringAndMessage = value; + // ReSharper disable once RedundantArgumentDefaultValue + RaisePropertyChanged("BoolPropertyWithStringAndMessage", oldValue, value, true); + } + } + + private bool _boolPropertyWithSetAndString; + + public bool BoolPropertyWithSetAndString + { + get + { + return _boolPropertyWithSetAndString; + } + set + { + Set("BoolPropertyWithSetAndString", ref _boolPropertyWithSetAndString, value); + } + } + + + private bool _boolPropertyWithSetAndExpression; + + public bool BoolPropertyWithSetAndExpression + { + get + { + return _boolPropertyWithSetAndExpression; + } + set + { + Set(() => BoolPropertyWithSetAndExpression, ref _boolPropertyWithSetAndExpression, value); + } + } + + private bool _boolPropertyWithSetAndExpressionAndMessage; + + public bool BoolPropertyWithSetAndExpressionAndMessage + { + get + { + return _boolPropertyWithSetAndExpressionAndMessage; + } + set + { + Set(() => BoolPropertyWithSetAndExpressionAndMessage, ref _boolPropertyWithSetAndExpressionAndMessage, value, true); + } + } + + + private bool _boolPropertyWithSetAndStringAndMessage; + + public bool BoolPropertyWithSetAndStringAndMessage + { + get + { + return _boolPropertyWithSetAndStringAndMessage; + } + set + { + Set("BoolPropertyWithSetAndStringAndMessage", ref _boolPropertyWithSetAndStringAndMessage, value, true); + } + } + } +} diff --git a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModelBaseAndPropertyChangedTest.cs b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModelBaseAndPropertyChangedTest.cs new file mode 100644 index 0000000..31842c4 --- /dev/null +++ b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PNET45)/ViewModelBaseAndPropertyChangedTest.cs @@ -0,0 +1,249 @@ +using System.Diagnostics.CodeAnalysis; +using GalaSoft.MvvmLight.Messaging; +using GalaSoft.MvvmLight.Test.ViewModel; + +#if NETFX_CORE || (WINDOWS_PHONE && !WINDOWS_PHONE7) +using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; +#else +using Microsoft.VisualStudio.TestTools.UnitTesting; +#endif + +namespace GalaSoft.MvvmLight.Test +{ + [TestClass] + [SuppressMessage("ReSharper", "InconsistentNaming")] + public class ViewModelBaseAndPropertyChangedTest + { + [TestMethod] + public void RaisePropertyChanged_WithString_ShouldCallRaisePropertyChangedWithStringOnly() + { + var testObject = new TestViewModelForPropertyChanged(); + + var eventWasRaised = false; + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithString") + { + eventWasRaised = true; + } + }; + + Assert.IsFalse(testObject.BoolPropertyWithString); + testObject.BoolPropertyWithString = true; + Assert.IsTrue(testObject.BoolPropertyWithString); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsFalse(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + + [TestMethod] + public void RaisePropertyChanged_WithExpression_ShouldCallRaisePropertyChangedWithStringAndWithExpression() + { + var testObject = new TestViewModelForPropertyChanged(); + + var eventWasRaised = false; + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithExpression") + { + eventWasRaised = true; + } + }; + + Assert.IsFalse(testObject.BoolPropertyWithExpression); + testObject.BoolPropertyWithExpression = true; + Assert.IsTrue(testObject.BoolPropertyWithExpression); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsTrue(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + + [TestMethod] + public void RaisePropertyChanged_WithExpressionAndMessage_ShouldCallRaisePropertyChangedWithStringAndWithExpression() + { + var testObject = new TestViewModelForPropertyChanged(); + + var eventWasRaised = false; + var messageWasReceived = false; + + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithExpressionAndMessage") + { + eventWasRaised = true; + } + }; + + Messenger.Default.Register>( + this, + message => + { + if (message.PropertyName == "BoolPropertyWithExpressionAndMessage" + && message.Sender == testObject) + { + messageWasReceived = true; + } + }); + + Assert.IsFalse(testObject.BoolPropertyWithExpressionAndMessage); + testObject.BoolPropertyWithExpressionAndMessage = true; + Assert.IsTrue(testObject.BoolPropertyWithExpressionAndMessage); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(messageWasReceived); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsTrue(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + + [TestMethod] + public void RaisePropertyChanged_WithSetAndExpression_ShouldCallRaisePropertyChangedWithStringAndWithExpression() + { + var testObject = new TestViewModelForPropertyChanged(); + + var eventWasRaised = false; + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithSetAndExpression") + { + eventWasRaised = true; + } + }; + + Assert.IsFalse(testObject.BoolPropertyWithSetAndExpression); + testObject.BoolPropertyWithSetAndExpression = true; + Assert.IsTrue(testObject.BoolPropertyWithSetAndExpression); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsTrue(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + + [TestMethod] + public void RaisePropertyChanged_WithSetAndExpressionAndMessage_ShouldCallRaisePropertyChangedWithStringAndWithExpression() + { + var testObject = new TestViewModelForPropertyChanged(); + + var eventWasRaised = false; + var messageWasReceived = false; + + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithSetAndExpressionAndMessage") + { + eventWasRaised = true; + } + }; + + Messenger.Default.Register>( + this, + message => + { + if (message.PropertyName == "BoolPropertyWithSetAndExpressionAndMessage" + && message.Sender == testObject) + { + messageWasReceived = true; + } + }); + + Assert.IsFalse(testObject.BoolPropertyWithSetAndExpressionAndMessage); + testObject.BoolPropertyWithSetAndExpressionAndMessage = true; + Assert.IsTrue(testObject.BoolPropertyWithSetAndExpressionAndMessage); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(messageWasReceived); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsTrue(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + + [TestMethod] + public void RaisePropertyChanged_WithSetAndString_ShouldCallRaisePropertyChangedWithStringOnly() + { + var testObject = new TestViewModelForPropertyChanged(); + + var eventWasRaised = false; + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithSetAndString") + { + eventWasRaised = true; + } + }; + + Assert.IsFalse(testObject.BoolPropertyWithSetAndString); + testObject.BoolPropertyWithSetAndString = true; + Assert.IsTrue(testObject.BoolPropertyWithSetAndString); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsFalse(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + + [TestMethod] + public void RaisePropertyChanged_WithSetAndStringAndMessage_ShouldCallRaisePropertyChangedWithStringOnly() + { + var testObject = new TestViewModelForPropertyChanged(); + + var eventWasRaised = false; + var messageWasReceived = false; + + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithSetAndStringAndMessage") + { + eventWasRaised = true; + } + }; + + Messenger.Default.Register>( + this, + message => + { + if (message.PropertyName == "BoolPropertyWithSetAndStringAndMessage" + && message.Sender == testObject) + { + messageWasReceived = true; + } + }); + + Assert.IsFalse(testObject.BoolPropertyWithSetAndStringAndMessage); + testObject.BoolPropertyWithSetAndStringAndMessage = true; + Assert.IsTrue(testObject.BoolPropertyWithSetAndStringAndMessage); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(messageWasReceived); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsFalse(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + + [TestMethod] + public void RaisePropertyChanged_WithStringAndMessage_ShouldCallRaisePropertyChangedWithStringOnly() + { + var testObject = new TestViewModelForPropertyChanged(); + + var eventWasRaised = false; + var messageWasReceived = false; + + testObject.PropertyChanged += (s, e) => + { + if (e.PropertyName == "BoolPropertyWithStringAndMessage") + { + eventWasRaised = true; + } + }; + + Messenger.Default.Register>( + this, + message => + { + if (message.PropertyName == "BoolPropertyWithStringAndMessage" + && message.Sender == testObject) + { + messageWasReceived = true; + } + }); + + Assert.IsFalse(testObject.BoolPropertyWithStringAndMessage); + testObject.BoolPropertyWithStringAndMessage = true; + Assert.IsTrue(testObject.BoolPropertyWithStringAndMessage); + Assert.IsTrue(eventWasRaised); + Assert.IsTrue(messageWasReceived); + Assert.IsTrue(testObject.RaisePropertyChangedWithPropertyNameWasCalled); + Assert.IsFalse(testObject.RaisePropertyChangedWithExpressionWasCalled); + } + } +} diff --git a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWIN81)/GalaSoft.MvvmLight.Test (PWIN81).csproj b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWIN81)/GalaSoft.MvvmLight.Test (PWIN81).csproj index 3448e7d..0bbdb87 100644 --- a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWIN81)/GalaSoft.MvvmLight.Test (PWIN81).csproj +++ b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWIN81)/GalaSoft.MvvmLight.Test (PWIN81).csproj @@ -260,6 +260,9 @@ ObservableObjectPropertyChangedTest.cs + + ObservableObjectTest.cs + Properties\AssemblyInfo.cs @@ -305,15 +308,24 @@ Threading\DispatcherHelperTest.cs + + ViewModelBaseAndPropertyChangedTest.cs + ViewModelBaseTest.cs ViewModel\TestClassWithObservableObject.cs + + ViewModel\TestObservableObject.cs + ViewModel\TestViewModel.cs + + ViewModel\TestViewModelForPropertyChanged.cs + ViewModel\TestViewModelNoMagicString.cs diff --git a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWP81)/GalaSoft.MvvmLight.Test (PWP81).csproj b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWP81)/GalaSoft.MvvmLight.Test (PWP81).csproj index 59b3836..2881310 100644 --- a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWP81)/GalaSoft.MvvmLight.Test (PWP81).csproj +++ b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWP81)/GalaSoft.MvvmLight.Test (PWP81).csproj @@ -220,6 +220,9 @@ ObservableObjectPropertyChangedTest.cs + + ObservableObjectTest.cs + Properties\AssemblyInfo.cs @@ -265,15 +268,24 @@ Threading\DispatcherHelperTest.cs + + ViewModelBaseAndPropertyChangedTest.cs + ViewModelBaseTest.cs ViewModel\TestClassWithObservableObject.cs + + ViewModel\TestObservableObject.cs + ViewModel\TestViewModel.cs + + ViewModel\TestViewModelForPropertyChanged.cs + ViewModel\TestViewModelNoMagicString.cs diff --git a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWPSL80)/GalaSoft.MvvmLight.Test (PWPSL80).csproj b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWPSL80)/GalaSoft.MvvmLight.Test (PWPSL80).csproj index 05ae1c2..79a8090 100644 --- a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWPSL80)/GalaSoft.MvvmLight.Test (PWPSL80).csproj +++ b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWPSL80)/GalaSoft.MvvmLight.Test (PWPSL80).csproj @@ -229,6 +229,9 @@ ObservableObjectPropertyChangedTest.cs + + ObservableObjectTest.cs + Properties\AssemblyInfo.cs @@ -274,15 +277,24 @@ Threading\DispatcherHelperTest.cs + + ViewModelBaseAndPropertyChangedTest.cs + ViewModelBaseTest.cs ViewModel\TestClassWithObservableObject.cs + + ViewModel\TestObservableObject.cs + ViewModel\TestViewModel.cs + + ViewModel\TestViewModelForPropertyChanged.cs + ViewModel\TestViewModelNoMagicString.cs diff --git a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWPSL81)/GalaSoft.MvvmLight.Test (PWPSL81).csproj b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWPSL81)/GalaSoft.MvvmLight.Test (PWPSL81).csproj index f603611..b6c7cb5 100644 --- a/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWPSL81)/GalaSoft.MvvmLight.Test (PWPSL81).csproj +++ b/GalaSoft.MvvmLight/Tests/PCL/GalaSoft.MvvmLight.Test (PWPSL81)/GalaSoft.MvvmLight.Test (PWPSL81).csproj @@ -230,6 +230,9 @@ ObservableObjectPropertyChangedTest.cs + + ObservableObjectTest.cs + Properties\AssemblyInfo.cs @@ -281,9 +284,15 @@ ViewModel\TestClassWithObservableObject.cs + + ViewModel\TestObservableObject.cs + ViewModel\TestViewModel.cs + + ViewModel\TestViewModelForPropertyChanged.cs + ViewModel\TestViewModelNoMagicString.cs @@ -378,7 +387,9 @@ ..\..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll - + + ..\..\..\_Binaries\Release\WPSL81\System.Windows.Interactivity.dll +