diff --git a/build/SourceLink.props b/build/SourceLink.props
index 1e007e01eb..0f77c2a613 100644
--- a/build/SourceLink.props
+++ b/build/SourceLink.props
@@ -3,7 +3,7 @@
true
false
true
- embedded
+ full
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
diff --git a/src/Avalonia.Animation/Animators/Animator`1.cs b/src/Avalonia.Animation/Animators/Animator`1.cs
index d784227620..23afa76bf6 100644
--- a/src/Avalonia.Animation/Animators/Animator`1.cs
+++ b/src/Avalonia.Animation/Animators/Animator`1.cs
@@ -79,15 +79,15 @@ namespace Avalonia.Animation.Animators
T oldValue, newValue;
- if (firstKeyframe.isNeutral)
- oldValue = neutralValue;
+ if (!firstKeyframe.isNeutral && firstKeyframe.Value is T firstKeyframeValue)
+ oldValue = firstKeyframeValue;
else
- oldValue = (T)firstKeyframe.Value;
+ oldValue = neutralValue;
- if (lastKeyframe.isNeutral)
- newValue = neutralValue;
+ if (!lastKeyframe.isNeutral && lastKeyframe.Value is T lastKeyframeValue)
+ newValue = lastKeyframeValue;
else
- newValue = (T)lastKeyframe.Value;
+ newValue = neutralValue;
if (lastKeyframe.KeySpline != null)
progress = lastKeyframe.KeySpline.GetSplineProgress(progress);
diff --git a/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs b/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs
index a5495fdfc9..6a95c2e047 100644
--- a/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs
+++ b/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs
@@ -85,7 +85,9 @@ namespace Avalonia.Controls.Platform
public bool CurrentThreadIsLoopThread => TlsCurrentThreadIsLoopThread;
public event Action Signaled;
+#pragma warning disable CS0067
public event Action Tick;
+#pragma warning restore CS0067
}
}
diff --git a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs
index e8122dd311..c5a729afae 100644
--- a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs
+++ b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs
@@ -18,7 +18,7 @@ namespace Avalonia.Controls
public bool SupportsSurroundingText => false;
public TextInputMethodSurroundingText SurroundingText => throw new NotSupportedException();
- public event EventHandler SurroundingTextChanged;
+ public event EventHandler SurroundingTextChanged { add { } remove { } }
public string TextBeforeCursor => null;
public string TextAfterCursor => null;
diff --git a/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs b/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs
index 0448a5c05d..45a6c97954 100644
--- a/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs
+++ b/src/Avalonia.DesignerSupport/Remote/FileWatcherTransport.cs
@@ -59,7 +59,7 @@ namespace Avalonia.DesignerSupport.Remote
remove { _onMessage -= value; }
}
- public event Action OnException;
+ public event Action OnException { add { } remove { } }
public void Start()
{
UpdaterThread();
diff --git a/src/Avalonia.FreeDesktop/DBusMenuExporter.cs b/src/Avalonia.FreeDesktop/DBusMenuExporter.cs
index 9e426688d8..206c24ad5e 100644
--- a/src/Avalonia.FreeDesktop/DBusMenuExporter.cs
+++ b/src/Avalonia.FreeDesktop/DBusMenuExporter.cs
@@ -413,10 +413,10 @@ namespace Avalonia.FreeDesktop
#region Events
private event Action<((int, IDictionary)[] updatedProps, (int, string[])[] removedProps)>
- ItemsPropertiesUpdated;
+ ItemsPropertiesUpdated { add { } remove { } }
private event Action<(uint revision, int parent)> LayoutUpdated;
- private event Action<(int id, uint timestamp)> ItemActivationRequested;
- private event Action PropertiesChanged;
+ private event Action<(int id, uint timestamp)> ItemActivationRequested { add { } remove { } }
+ private event Action PropertiesChanged { add { } remove { } }
async Task IDBusMenu.WatchItemsPropertiesUpdatedAsync(Action<((int, IDictionary)[] updatedProps, (int, string[])[] removedProps)> handler, Action onError)
{
diff --git a/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs b/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
index 4431e108ed..1582f794ae 100644
--- a/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
+++ b/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
@@ -44,7 +44,7 @@ namespace Avalonia.Native
public bool IsNativeMenuExported => _exported;
- public event EventHandler OnIsNativeMenuExportedChanged;
+ public event EventHandler OnIsNativeMenuExportedChanged { add { } remove { } }
public void SetNativeMenu(NativeMenu menu)
{
diff --git a/src/Avalonia.Themes.Default/Expander.xaml b/src/Avalonia.Themes.Default/Expander.xaml
index 7df65677b6..e72ddea163 100644
--- a/src/Avalonia.Themes.Default/Expander.xaml
+++ b/src/Avalonia.Themes.Default/Expander.xaml
@@ -15,7 +15,7 @@
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
-
+
-
+
-
+
-
+
-
+
-
+
-
+
HandleEventAsync(RawKeyEventArgs args, int keyVal, int keyCode) =>
new ValueTask(false);
- public event Action Commit;
- public event Action ForwardKey;
+ public event Action Commit { add { } remove { } }
+ public event Action ForwardKey { add { } remove { } }
}
diff --git a/tests/Avalonia.Animation.UnitTests/AnimatableTests.cs b/tests/Avalonia.Animation.UnitTests/AnimatableTests.cs
index b01fb70f58..26d8059eec 100644
--- a/tests/Avalonia.Animation.UnitTests/AnimatableTests.cs
+++ b/tests/Avalonia.Animation.UnitTests/AnimatableTests.cs
@@ -1,5 +1,7 @@
using System;
+using Avalonia.Animation.Animators;
using Avalonia.Controls;
+using Avalonia.Controls.Shapes;
using Avalonia.Data;
using Avalonia.Layout;
using Avalonia.Media;
@@ -100,6 +102,71 @@ namespace Avalonia.Animation.UnitTests
Times.Never);
}
+
+ [Theory]
+ [InlineData(null)] //null value
+ [InlineData("stringValue")] //string value
+ public void Invalid_Values_In_Animation_Should_Not_Crash_Animations(object invalidValue)
+ {
+ var keyframe1 = new KeyFrame()
+ {
+ Setters =
+ {
+ new Setter(Layoutable.WidthProperty, 1d),
+ },
+ KeyTime = TimeSpan.FromSeconds(0)
+ };
+
+ var keyframe2 = new KeyFrame()
+ {
+ Setters =
+ {
+ new Setter(Layoutable.WidthProperty, 2d),
+ },
+ KeyTime = TimeSpan.FromSeconds(2),
+ };
+
+ var keyframe3 = new KeyFrame()
+ {
+ Setters =
+ {
+ new Setter(Layoutable.WidthProperty, invalidValue),
+ },
+ KeyTime = TimeSpan.FromSeconds(3),
+ };
+
+ var animation = new Animation()
+ {
+ Duration = TimeSpan.FromSeconds(3),
+ Children =
+ {
+ keyframe1,
+ keyframe2,
+ keyframe3
+ },
+ IterationCount = new IterationCount(5),
+ PlaybackDirection = PlaybackDirection.Alternate,
+ };
+
+ var rect = new Rectangle()
+ {
+ Width = 11,
+ };
+
+ var originalValue = rect.Width;
+
+ var clock = new TestClock();
+ var animationRun = animation.RunAsync(rect, clock);
+
+ clock.Step(TimeSpan.Zero);
+ Assert.Equal(rect.Width, 1);
+ clock.Step(TimeSpan.FromSeconds(2));
+ Assert.Equal(rect.Width, 2);
+ clock.Step(TimeSpan.FromSeconds(3));
+ //here we have invalid value so value should be expected and set to initial original value
+ Assert.Equal(rect.Width, originalValue);
+ }
+
[Fact]
public void Transition_Is_Not_Applied_When_StyleTrigger_Changes_With_LocalValue_Present()
{
diff --git a/tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs b/tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs
index 529b3b1aa8..22a9b28648 100644
--- a/tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/ItemsSourceViewTests.cs
@@ -47,7 +47,7 @@ namespace Avalonia.Controls.UnitTests
private class InvalidCollection : INotifyCollectionChanged, IEnumerable
{
- public event NotifyCollectionChangedEventHandler CollectionChanged;
+ public event NotifyCollectionChangedEventHandler CollectionChanged { add { } remove { } }
public IEnumerator GetEnumerator()
{