Browse Source

Fixed panel collection change actions.

As suggested in #1286
pull/1301/head
Steven Kirk 8 years ago
parent
commit
fc7a83ee72
  1. 15
      src/Avalonia.Base/Collections/IAvaloniaList.cs
  2. 11
      src/Avalonia.Controls/Panel.cs
  3. 13
      src/Avalonia.Visuals/Visual.cs
  4. 63
      tests/Avalonia.Controls.UnitTests/PanelTests.cs

15
src/Avalonia.Base/Collections/IAvaloniaList.cs

@ -36,6 +36,21 @@ namespace Avalonia.Collections
/// <param name="items">The items.</param>
void InsertRange(int index, IEnumerable<T> items);
/// <summary>
/// Moves an item to a new index.
/// </summary>
/// <param name="oldIndex">The index of the item to move.</param>
/// <param name="newIndex">The index to move the item to.</param>
void Move(int oldIndex, int newIndex);
/// <summary>
/// Moves multiple items to a new index.
/// </summary>
/// <param name="oldIndex">The first index of the items to move.</param>
/// <param name="count">The number of items to move.</param>
/// <param name="newIndex">The index to move the items to.</param>
void MoveRange(int oldIndex, int count, int newIndex);
/// <summary>
/// Removes multiple items from the collection.
/// </summary>

11
src/Avalonia.Controls/Panel.cs

@ -115,6 +115,11 @@ namespace Avalonia.Controls
VisualChildren.AddRange(e.NewItems.OfType<Visual>());
break;
case NotifyCollectionChangedAction.Move:
LogicalChildren.MoveRange(e.OldStartingIndex, e.OldItems.Count, e.NewStartingIndex);
VisualChildren.MoveRange(e.OldStartingIndex, e.OldItems.Count, e.NewStartingIndex);
break;
case NotifyCollectionChangedAction.Remove:
controls = e.OldItems.OfType<Control>().ToList();
LogicalChildren.RemoveAll(controls);
@ -132,11 +137,7 @@ namespace Avalonia.Controls
break;
case NotifyCollectionChangedAction.Reset:
controls = e.OldItems.OfType<Control>().ToList();
LogicalChildren.Clear();
VisualChildren.Clear();
VisualChildren.AddRange(_children);
break;
throw new NotSupportedException();
}
InvalidateMeasure();

13
src/Avalonia.Visuals/Visual.cs

@ -537,6 +537,19 @@ namespace Avalonia
v.SetVisualParent(null);
}
break;
case NotifyCollectionChangedAction.Replace:
foreach (Visual v in e.OldItems)
{
v.SetVisualParent(null);
}
foreach (Visual v in e.NewItems)
{
v.SetVisualParent(this);
}
break;
}
}

63
tests/Avalonia.Controls.UnitTests/PanelTests.cs

@ -4,6 +4,7 @@
using System.Linq;
using Avalonia.Collections;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
using Xunit;
namespace Avalonia.Controls.UnitTests
@ -18,8 +19,9 @@ namespace Avalonia.Controls.UnitTests
panel.Children.Add(child);
Assert.Equal(child.Parent, panel);
Assert.Equal(child.GetLogicalParent(), panel);
Assert.Same(child.Parent, panel);
Assert.Same(child.GetLogicalParent(), panel);
Assert.Same(child.GetVisualParent(), panel);
}
[Fact]
@ -45,6 +47,7 @@ namespace Avalonia.Controls.UnitTests
Assert.Null(child.Parent);
Assert.Null(child.GetLogicalParent());
Assert.Null(child.GetVisualParent());
}
[Fact]
@ -60,8 +63,10 @@ namespace Avalonia.Controls.UnitTests
Assert.Null(child1.Parent);
Assert.Null(child1.GetLogicalParent());
Assert.Null(child1.GetVisualParent());
Assert.Null(child2.Parent);
Assert.Null(child2.GetLogicalParent());
Assert.Null(child2.GetVisualParent());
}
[Fact]
@ -77,24 +82,32 @@ namespace Avalonia.Controls.UnitTests
Assert.Null(child1.Parent);
Assert.Null(child1.GetLogicalParent());
Assert.Null(child1.GetVisualParent());
Assert.Null(child2.Parent);
Assert.Null(child2.GetLogicalParent());
Assert.Null(child2.GetVisualParent());
}
[Fact]
public void Setting_Children_Should_Make_Controls_Appear_In_Panel_Children()
public void Replacing_Panel_Children_Should_Clear_And_Set_Control_Parent()
{
var panel = new Panel();
var child = new Control();
var child1 = new Control();
var child2 = new Control();
panel.Children = new Controls { child };
panel.Children.Add(child1);
panel.Children[0] = child2;
Assert.Equal(new[] { child }, panel.Children);
Assert.Equal(new[] { child }, panel.GetLogicalChildren());
Assert.Null(child1.Parent);
Assert.Null(child1.GetLogicalParent());
Assert.Null(child1.GetVisualParent());
Assert.Same(child2.Parent, panel);
Assert.Same(child2.GetLogicalParent(), panel);
Assert.Same(child2.GetVisualParent(), panel);
}
[Fact]
public void Child_Control_Should_Appear_In_Panel_Children()
public void Child_Control_Should_Appear_In_Panel_Logical_And_Visual_Children()
{
var panel = new Panel();
var child = new Control();
@ -103,10 +116,11 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(new[] { child }, panel.Children);
Assert.Equal(new[] { child }, panel.GetLogicalChildren());
Assert.Equal(new[] { child }, panel.GetVisualChildren());
}
[Fact]
public void Removing_Child_Control_Should_Remove_From_Panel_Children()
public void Removing_Child_Control_Should_Remove_From_Panel_Logical_And_Visual_Children()
{
var panel = new Panel();
var child = new Control();
@ -115,7 +129,36 @@ namespace Avalonia.Controls.UnitTests
panel.Children.Remove(child);
Assert.Equal(new Control[0], panel.Children);
Assert.Equal(new ILogical[0], panel.GetLogicalChildren());
Assert.Empty(panel.GetLogicalChildren());
Assert.Empty(panel.GetVisualChildren());
}
[Fact]
public void Moving_Panel_Children_Should_Reoder_Logical_And_Visual_Children()
{
var panel = new Panel();
var child1 = new Control();
var child2 = new Control();
panel.Children.Add(child1);
panel.Children.Add(child2);
panel.Children.Move(1, 0);
Assert.Equal(new[] { child2, child1 }, panel.GetLogicalChildren());
Assert.Equal(new[] { child2, child1 }, panel.GetVisualChildren());
}
[Fact]
public void Setting_Children_Should_Make_Controls_Appear_In_Logical_And_Visual_Children()
{
var panel = new Panel();
var child = new Control();
panel.Children = new Controls { child };
Assert.Equal(new[] { child }, panel.Children);
Assert.Equal(new[] { child }, panel.GetLogicalChildren());
Assert.Equal(new[] { child }, panel.GetVisualChildren());
}
}
}

Loading…
Cancel
Save