diff --git a/src/Avalonia.Base/Data/Converters/DefaultValueConverter.cs b/src/Avalonia.Base/Data/Converters/DefaultValueConverter.cs
index 990a4b04f2..0ffd6a9539 100644
--- a/src/Avalonia.Base/Data/Converters/DefaultValueConverter.cs
+++ b/src/Avalonia.Base/Data/Converters/DefaultValueConverter.cs
@@ -31,7 +31,7 @@ namespace Avalonia.Data.Converters
{
if (value == null)
{
- return AvaloniaProperty.UnsetValue;
+ return targetType.IsValueType ? AvaloniaProperty.UnsetValue : null;
}
if (typeof(ICommand).IsAssignableFrom(targetType) && value is Delegate d && d.Method.GetParameters().Length <= 1)
diff --git a/src/Avalonia.Controls/ListBox.cs b/src/Avalonia.Controls/ListBox.cs
index 3150b6be91..f26cd47bcb 100644
--- a/src/Avalonia.Controls/ListBox.cs
+++ b/src/Avalonia.Controls/ListBox.cs
@@ -68,7 +68,13 @@ namespace Avalonia.Controls
///
public new IList SelectedItems => base.SelectedItems;
- ///
+ ///
+ /// Gets or sets the selection mode.
+ ///
+ ///
+ /// Note that the selection mode only applies to selections made via user interaction.
+ /// Multiple selections can be made programatically regardless of the value of this property.
+ ///
public new SelectionMode SelectionMode
{
get { return base.SelectionMode; }
diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
index 91a9fa7e40..4f01f5467b 100644
--- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
+++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
@@ -222,6 +222,10 @@ namespace Avalonia.Controls.Primitives
///
/// Gets or sets the selection mode.
///
+ ///
+ /// Note that the selection mode only applies to selections made via user interaction.
+ /// Multiple selections can be made programatically regardless of the value of this property.
+ ///
protected SelectionMode SelectionMode
{
get { return GetValue(SelectionModeProperty); }
@@ -338,24 +342,36 @@ namespace Avalonia.Controls.Primitives
{
base.OnContainersMaterialized(e);
- var selectedIndex = SelectedIndex;
- var selectedContainer = e.Containers
- .FirstOrDefault(x => (x.ContainerControl as ISelectable)?.IsSelected == true);
+ var resetSelectedItems = false;
- if (selectedContainer != null)
+ foreach (var container in e.Containers)
{
- SelectedIndex = selectedContainer.Index;
- }
- else if (selectedIndex >= e.StartingIndex &&
- selectedIndex < e.StartingIndex + e.Containers.Count)
- {
- var container = e.Containers[selectedIndex - e.StartingIndex];
+ if ((container.ContainerControl as ISelectable)?.IsSelected == true)
+ {
+ if (SelectedIndex == -1)
+ {
+ SelectedIndex = container.Index;
+ }
+ else
+ {
+ if (_selection.Add(container.Index))
+ {
+ resetSelectedItems = true;
+ }
+ }
- if (container.ContainerControl != null)
+ MarkContainerSelected(container.ContainerControl, true);
+ }
+ else if (_selection.Contains(container.Index))
{
MarkContainerSelected(container.ContainerControl, true);
}
}
+
+ if (resetSelectedItems)
+ {
+ ResetSelectedItems();
+ }
}
///
diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_DataValidation.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_DataValidation.cs
index b12b2e3c31..428f878945 100644
--- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_DataValidation.cs
+++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_DataValidation.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reactive.Subjects;
using Avalonia.Data;
+using Avalonia.UnitTests;
using Xunit;
namespace Avalonia.Base.UnitTests
@@ -34,10 +35,10 @@ namespace Avalonia.Base.UnitTests
{
var target = new Class1();
- target.SetValue(Class1.ValidatedDirectProperty, new BindingNotification(6));
- target.SetValue(Class1.ValidatedDirectProperty, new BindingNotification(new Exception(), BindingErrorType.Error));
- target.SetValue(Class1.ValidatedDirectProperty, new BindingNotification(new Exception(), BindingErrorType.DataValidationError));
- target.SetValue(Class1.ValidatedDirectProperty, new BindingNotification(7));
+ target.SetValue(Class1.ValidatedDirectIntProperty, new BindingNotification(6));
+ target.SetValue(Class1.ValidatedDirectIntProperty, new BindingNotification(new Exception(), BindingErrorType.Error));
+ target.SetValue(Class1.ValidatedDirectIntProperty, new BindingNotification(new Exception(), BindingErrorType.DataValidationError));
+ target.SetValue(Class1.ValidatedDirectIntProperty, new BindingNotification(7));
Assert.Equal(
new[]
@@ -73,7 +74,7 @@ namespace Avalonia.Base.UnitTests
var source = new Subject