Browse Source

Merge branch 'master' into release/0.10.2

release/0.10.2
Steven Kirk 5 years ago
parent
commit
24510f98a4
  1. 2
      src/Avalonia.Controls/Control.cs
  2. 34
      src/Avalonia.Controls/Selection/InternalSelectionModel.cs
  3. 1
      src/Avalonia.Themes.Default/TextBox.xaml
  4. 1
      src/Avalonia.Themes.Fluent/Controls/TextBox.xaml
  5. 28
      tests/Avalonia.Controls.UnitTests/ListBoxTests.cs

2
src/Avalonia.Controls/Control.cs

@ -37,7 +37,6 @@ namespace Avalonia.Controls
/// <summary>
/// Defines the <see cref="ContextMenu"/> property.
/// </summary>
[Obsolete("Prefer ContextFlyout")]
public static readonly StyledProperty<ContextMenu?> ContextMenuProperty =
AvaloniaProperty.Register<Control, ContextMenu?>(nameof(ContextMenu));
@ -77,7 +76,6 @@ namespace Avalonia.Controls
/// <summary>
/// Gets or sets a context menu to the control.
/// </summary>
[Obsolete("Prefer ContextFlyout")]
public ContextMenu? ContextMenu
{
get => GetValue(ContextMenuProperty);

34
src/Avalonia.Controls/Selection/InternalSelectionModel.cs

@ -80,10 +80,12 @@ namespace Avalonia.Controls.Selection
try
{
_ignoreSelectedItemsChanges = true;
++_ignoreModelChanges;
base.SetSource(value);
}
finally
{
--_ignoreModelChanges;
_ignoreSelectedItemsChanges = false;
}
@ -93,17 +95,14 @@ namespace Avalonia.Controls.Selection
}
else
{
foreach (var i in oldSelection)
{
var index = ItemsView!.IndexOf(i);
Select(index);
}
SyncFromSelectedItems();
}
}
private void SyncToSelectedItems()
{
if (_writableSelectedItems is object)
if (_writableSelectedItems is object &&
!SequenceEqual(_writableSelectedItems, base.SelectedItems))
{
try
{
@ -224,6 +223,7 @@ namespace Avalonia.Controls.Selection
if (_isResetting)
{
--_ignoreModelChanges;
_isResetting = false;
}
}
@ -310,5 +310,27 @@ namespace Avalonia.Controls.Selection
return -1;
}
private static bool SequenceEqual(IList first, IReadOnlyList<object?> second)
{
if (first is IEnumerable<object?> e)
{
return e.SequenceEqual(second);
}
var comparer = EqualityComparer<object?>.Default;
var e1 = first.GetEnumerator();
using var e2 = second.GetEnumerator();
while (e1.MoveNext())
{
if (!(e2.MoveNext() && comparer.Equals(e1.Current, e2.Current)))
{
return false;
}
}
return !e2.MoveNext();
}
}
}

1
src/Avalonia.Themes.Default/TextBox.xaml

@ -10,7 +10,6 @@
<MenuItem x:Name="TextBoxContextFlyoutPasteItem" Header="Paste" Command="{Binding $parent[TextBox].Paste}" IsEnabled="{Binding $parent[TextBox].CanPaste}" InputGesture="{x:Static TextBox.PasteGesture}"/>
</MenuFlyout>
<!-- ContextMenu obsolete, prefer ContextFlyout -->
<ContextMenu x:Key="DefaultTextBoxContextMenu" x:Name="TextBoxContextMenu">
<MenuItem x:Name="TextBoxContextMenuCutItem" Header="Cut" Command="{Binding $parent[TextBox].Cut}" IsEnabled="{Binding $parent[TextBox].CanCut}" InputGesture="{x:Static TextBox.CutGesture}" />
<MenuItem x:Name="TextBoxContextMenuCopyItem" Header="Copy" Command="{Binding $parent[TextBox].Copy}" IsEnabled="{Binding $parent[TextBox].CanCopy}" InputGesture="{x:Static TextBox.CopyGesture}"/>

1
src/Avalonia.Themes.Fluent/Controls/TextBox.xaml

@ -21,7 +21,6 @@
<MenuItem x:Name="TextBoxContextFlyoutPasteItem" Header="Paste" Command="{Binding $parent[TextBox].Paste}" IsEnabled="{Binding $parent[TextBox].CanPaste}" InputGesture="{x:Static TextBox.PasteGesture}"/>
</MenuFlyout>
<!-- ContextMenu obsolete, prefer ContextFlyout -->
<ContextMenu x:Key="DefaultTextBoxContextMenu" x:Name="TextBoxContextMenu">
<MenuItem x:Name="TextBoxContextMenuCutItem" Header="Cut" Command="{Binding $parent[TextBox].Cut}" IsEnabled="{Binding $parent[TextBox].CanCut}" InputGesture="{x:Static TextBox.CutGesture}" />
<MenuItem x:Name="TextBoxContextMenuCopyItem" Header="Copy" Command="{Binding $parent[TextBox].Copy}" IsEnabled="{Binding $parent[TextBox].CanCopy}" InputGesture="{x:Static TextBox.CopyGesture}"/>

28
tests/Avalonia.Controls.UnitTests/ListBoxTests.cs

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Subjects;
using Avalonia.Collections;
@ -457,6 +458,33 @@ namespace Avalonia.Controls.UnitTests
}
}
[Fact]
public void Initial_Binding_Of_SelectedItems_Should_Not_Cause_Write_To_SelectedItems()
{
var target = new ListBox
{
[!ListBox.ItemsProperty] = new Binding("Items"),
[!ListBox.SelectedItemsProperty] = new Binding("SelectedItems"),
};
var viewModel = new
{
Items = new[] { "Foo", "Bar", "Baz " },
SelectedItems = new ObservableCollection<string> { "Bar" },
};
var raised = 0;
viewModel.SelectedItems.CollectionChanged += (s, e) => ++raised;
target.DataContext = viewModel;
Assert.Equal(0, raised);
Assert.Equal(new[] { "Bar" }, viewModel.SelectedItems);
Assert.Equal(new[] { "Bar" }, target.SelectedItems);
Assert.Equal(new[] { "Bar" }, target.Selection.SelectedItems);
}
private FuncControlTemplate ListBoxTemplate()
{
return new FuncControlTemplate<ListBox>((parent, scope) =>

Loading…
Cancel
Save