|
|
|
@ -1048,6 +1048,74 @@ namespace Avalonia.Controls.UnitTests |
|
|
|
Assert.Equal(new(0, 200), scroll.Offset); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void Can_Bind_Item_IsVisible() |
|
|
|
{ |
|
|
|
using var app = App(); |
|
|
|
var style = CreateIsVisibleBindingStyle(); |
|
|
|
var items = Enumerable.Range(0, 100).Select(x => new ItemWithIsVisible(x)).ToList(); |
|
|
|
var (target, scroll, itemsControl) = CreateTarget(items: items, styles: new[] { style }); |
|
|
|
var container = target.ContainerFromIndex(2)!; |
|
|
|
|
|
|
|
Assert.True(container.IsVisible); |
|
|
|
Assert.Equal(20, container.Bounds.Top); |
|
|
|
|
|
|
|
items[2].IsVisible = false; |
|
|
|
Layout(target); |
|
|
|
|
|
|
|
Assert.False(container.IsVisible); |
|
|
|
|
|
|
|
// Next container should be in correct position.
|
|
|
|
Assert.Equal(20, target.ContainerFromIndex(3)!.Bounds.Top); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void IsVisible_Binding_Persists_After_Scrolling() |
|
|
|
{ |
|
|
|
using var app = App(); |
|
|
|
var style = CreateIsVisibleBindingStyle(); |
|
|
|
var items = Enumerable.Range(0, 100).Select(x => new ItemWithIsVisible(x)).ToList(); |
|
|
|
var (target, scroll, itemsControl) = CreateTarget(items: items, styles: new[] { style }); |
|
|
|
var container = target.ContainerFromIndex(2)!; |
|
|
|
|
|
|
|
Assert.True(container.IsVisible); |
|
|
|
Assert.Equal(20, container.Bounds.Top); |
|
|
|
|
|
|
|
items[2].IsVisible = false; |
|
|
|
scroll.Offset = new Vector(0, 200); |
|
|
|
Layout(target); |
|
|
|
|
|
|
|
scroll.Offset = new Vector(0, 0); |
|
|
|
Layout(target); |
|
|
|
|
|
|
|
container = target.ContainerFromIndex(2)!; |
|
|
|
Assert.False(container.IsVisible); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void Recycling_A_Hidden_Control_Shows_It() |
|
|
|
{ |
|
|
|
using var app = App(); |
|
|
|
var style = CreateIsVisibleBindingStyle(); |
|
|
|
var items = Enumerable.Range(0, 3).Select(x => new ItemWithIsVisible(x)).ToList(); |
|
|
|
var (target, scroll, itemsControl) = CreateTarget(items: items, styles: new[] { style }); |
|
|
|
var container = target.ContainerFromIndex(2)!; |
|
|
|
|
|
|
|
Assert.True(container.IsVisible); |
|
|
|
Assert.Equal(20, container.Bounds.Top); |
|
|
|
|
|
|
|
items[2].IsVisible = false; |
|
|
|
Layout(target); |
|
|
|
|
|
|
|
Assert.False(container.IsVisible); |
|
|
|
|
|
|
|
items.RemoveAt(2); |
|
|
|
items.Add(new ItemWithIsVisible(3)); |
|
|
|
Layout(target); |
|
|
|
|
|
|
|
Assert.True(container.IsVisible); |
|
|
|
} |
|
|
|
|
|
|
|
private static IReadOnlyList<int> GetRealizedIndexes(VirtualizingStackPanel target, ItemsControl itemsControl) |
|
|
|
{ |
|
|
|
return target.GetRealizedElements() |
|
|
|
@ -1173,6 +1241,17 @@ namespace Avalonia.Controls.UnitTests |
|
|
|
return root; |
|
|
|
} |
|
|
|
|
|
|
|
private static Style CreateIsVisibleBindingStyle() |
|
|
|
{ |
|
|
|
return new Style(x => x.OfType<ContentPresenter>()) |
|
|
|
{ |
|
|
|
Setters = |
|
|
|
{ |
|
|
|
new Setter(Visual.IsVisibleProperty, new Binding("IsVisible")), |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
private static IDataTemplate DefaultItemTemplate() |
|
|
|
{ |
|
|
|
return new FuncDataTemplate<object>((x, _) => new Canvas { Width = 100, Height = 10 }); |
|
|
|
@ -1218,6 +1297,24 @@ namespace Avalonia.Controls.UnitTests |
|
|
|
public double Height { get; set; } |
|
|
|
} |
|
|
|
|
|
|
|
private class ItemWithIsVisible : NotifyingBase |
|
|
|
{ |
|
|
|
private bool _isVisible = true; |
|
|
|
|
|
|
|
public ItemWithIsVisible(int index) |
|
|
|
{ |
|
|
|
Caption = $"Item {index}"; |
|
|
|
} |
|
|
|
|
|
|
|
public string Caption { get; set; } |
|
|
|
|
|
|
|
public bool IsVisible |
|
|
|
{ |
|
|
|
get => _isVisible; |
|
|
|
set => SetField(ref _isVisible, value); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private class ResettingCollection : List<string>, INotifyCollectionChanged |
|
|
|
{ |
|
|
|
public ResettingCollection(IEnumerable<string> items) |
|
|
|
|