diff --git a/src/net/Qml.Net.Tests/Qml/SignalTests.cs b/src/net/Qml.Net.Tests/Qml/SignalTests.cs
index 9c55fff8..dcb61f06 100644
--- a/src/net/Qml.Net.Tests/Qml/SignalTests.cs
+++ b/src/net/Qml.Net.Tests/Qml/SignalTests.cs
@@ -31,6 +31,47 @@ namespace Qml.Net.Tests.Qml
{
}
+
+ private string _someStringPropertyValue = "";
+
+ [NotifySignal]
+ public string SomeStringProperty
+ {
+ get => _someStringPropertyValue;
+ set {
+ if (_someStringPropertyValue == value)
+ return;
+ _someStringPropertyValue = value;
+ this.ActivateNotifySignal();
+ }
+ }
+
+ private int _someIntPropertyValue = 0;
+
+ [NotifySignal("someWeirdSignalName")]
+ public int SomeIntProperty
+ {
+ get => _someIntPropertyValue;
+ set {
+ if (_someIntPropertyValue == value)
+ return;
+ _someIntPropertyValue = value;
+ this.ActivateNotifySignal();
+ }
+ }
+
+ private bool _someBoolPropertyValue = false;
+
+ public bool SomeBoolProperty
+ {
+ get => _someBoolPropertyValue;
+ set {
+ if (_someBoolPropertyValue == value)
+ return;
+ _someBoolPropertyValue = value;
+ this.ActivateNotifySignal();
+ }
+ }
}
[Signal("testSignal")]
@@ -153,6 +194,75 @@ namespace Qml.Net.Tests.Qml
Mock.VerifySet(x => x.SignalRaised = true, Times.Once);
}
+ [Fact]
+ public void Can_raise_changed_default_signal_from_net()
+ {
+ Mock.Setup(x => x.SignalRaised).Returns(false);
+
+ NetTestHelper.RunQml(qmlApplicationEngine,
+ @"
+ import QtQuick 2.0
+ import tests 1.0
+ ObjectTestsQml {
+ id: test
+ Component.onCompleted: function() {
+ test.someStringPropertyChanged.connect(function() {
+ test.signalRaised = true
+ })
+ test.someStringProperty = 'NewValue'
+ }
+ }
+ ");
+
+ Mock.VerifySet(x => x.SignalRaised = true, Times.Once);
+ }
+
+ [Fact]
+ public void Can_raise_changed_custom_signal_from_net()
+ {
+ Mock.Setup(x => x.SignalRaised).Returns(false);
+
+ NetTestHelper.RunQml(qmlApplicationEngine,
+ @"
+ import QtQuick 2.0
+ import tests 1.0
+ ObjectTestsQml {
+ id: test
+ Component.onCompleted: function() {
+ test.someWeirdSignalName.connect(function() {
+ test.signalRaised = true
+ })
+ test.someIntProperty = 1
+ }
+ }
+ ");
+
+ Mock.VerifySet(x => x.SignalRaised = true, Times.Once);
+ }
+
+ [Fact]
+ public void Can_not_raise_invalid_changed_signal_from_net()
+ {
+ Mock.Setup(x => x.SignalRaised).Returns(false);
+
+ NetTestHelper.RunQml(qmlApplicationEngine,
+ @"
+ import QtQuick 2.0
+ import tests 1.0
+ ObjectTestsQml {
+ id: test
+ Component.onCompleted: function() {
+ test.someBoolPropertyChanged.connect(function() {
+ test.signalRaised = true
+ })
+ test.someBoolProperty = true
+ }
+ }
+ ");
+
+ Mock.VerifySet(x => x.SignalRaised = true, Times.Never);
+ }
+
[Fact]
public void Can_raise_signal_from_net_with_args()
{
diff --git a/src/net/Qml.Net/Signals.cs b/src/net/Qml.Net/Signals.cs
index 84bc59ad..3effcab0 100644
--- a/src/net/Qml.Net/Signals.cs
+++ b/src/net/Qml.Net/Signals.cs
@@ -1,4 +1,7 @@
-using Qml.Net.Internal;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using Qml.Net.Internal;
using Qml.Net.Internal.Types;
namespace Qml.Net
@@ -34,6 +37,35 @@ namespace Qml.Net
return true;
}
+ ///
+ /// Activates the signal that has been attached to the given property using NotifySignalAttribute
+ ///
+ /// object instance having the property the changed signal has to be activated for
+ ///
+ /// name of the property. Gets automatically filled with the caller member name.
+ /// So calling it directly out of the property that is tied to the signal doesn't need to set this parameter explicitly.
+ /// true when the signal has been activated, otherwise false
+ public static bool ActivateNotifySignal(this object instance, [CallerMemberName] string propertyName = "")
+ {
+ if (instance == null)
+ return false;
+ var propertyInfo =
+ instance.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public);
+ if (propertyInfo == null)
+ return false;
+ var notifySignalAttributes = propertyInfo.GetCustomAttributes().OfType();
+ var notifySignalAttribute = notifySignalAttributes.FirstOrDefault();
+ if (notifySignalAttribute == null)
+ return false;
+ var signalName = notifySignalAttribute.Name;
+ if (string.IsNullOrEmpty(signalName))
+ {
+ signalName = $"{propertyInfo.Name}Changed";
+ signalName = char.ToLower(signalName[0]) + signalName.Substring(1);
+ }
+ return ActivateSignal(instance, signalName);
+ }
+
public static void AttachToSignal(this object instance, string signalName, System.Delegate del)
{
instance.AttachDelegateToSignal(signalName, del);