Browse Source

Merge pull request #2813 from AvaloniaUI/fixes/2804-itemsrepeater-problems

Fix ItemsRepeater problems
pull/2818/head
Steven Kirk 7 years ago
committed by GitHub
parent
commit
dcf6821ef9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml
  2. 12
      samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs
  3. 27
      samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs
  4. 4
      src/Avalonia.Controls/Repeater/ItemsRepeater.cs
  5. 8
      src/Avalonia.Controls/Repeater/ItemsSourceView.cs
  6. 6
      src/Avalonia.Layout/UniformGridLayoutState.cs

5
samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml

@ -6,19 +6,20 @@
<TextBlock Classes="h1">ItemsRepeater</TextBlock>
<TextBlock Classes="h2">A data-driven collection control that incorporates a flexible layout system, custom views, and virtualization.</TextBlock>
</StackPanel>
<StackPanel DockPanel.Dock="Right" Margin="8 0">
<StackPanel DockPanel.Dock="Right" Margin="8 0" Spacing="4">
<ComboBox SelectedIndex="0" SelectionChanged="LayoutChanged">
<ComboBoxItem>Stack - Vertical</ComboBoxItem>
<ComboBoxItem>Stack - Horizontal</ComboBoxItem>
<ComboBoxItem>UniformGrid - Vertical</ComboBoxItem>
<ComboBoxItem>UniformGrid - Horizontal</ComboBoxItem>
</ComboBox>
<Button Command="{Binding AddItem}">Add Item</Button>
</StackPanel>
<Border BorderThickness="1" BorderBrush="{DynamicResource ThemeBorderMidBrush}" Margin="0 0 0 16">
<ScrollViewer Name="scroller"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<ItemsRepeater Name="repeater" Items="{Binding}"/>
<ItemsRepeater Name="repeater" Background="Transparent" Items="{Binding Items}"/>
</ScrollViewer>
</Border>
</DockPanel>

12
samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs

@ -1,8 +1,11 @@
using System;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Markup.Xaml;
using ControlCatalog.ViewModels;
namespace ControlCatalog.Pages
{
@ -16,7 +19,8 @@ namespace ControlCatalog.Pages
this.InitializeComponent();
_repeater = this.FindControl<ItemsRepeater>("repeater");
_scroller = this.FindControl<ScrollViewer>("scroller");
DataContext = Enumerable.Range(1, 100000).Select(i => $"Item {i}" ).ToArray();
_repeater.PointerPressed += RepeaterClick;
DataContext = new ItemsRepeaterPageViewModel();
}
private void InitializeComponent()
@ -67,5 +71,11 @@ namespace ControlCatalog.Pages
break;
}
}
private void RepeaterClick(object sender, PointerPressedEventArgs e)
{
var item = (e.Source as TextBlock)?.DataContext as string;
((ItemsRepeaterPageViewModel)DataContext).SelectedItem = item;
}
}
}

27
samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs

@ -0,0 +1,27 @@
using System.Collections.ObjectModel;
using System.Linq;
using ReactiveUI;
namespace ControlCatalog.ViewModels
{
public class ItemsRepeaterPageViewModel : ReactiveObject
{
private int newItemIndex = 1;
public ItemsRepeaterPageViewModel()
{
Items = new ObservableCollection<string>(
Enumerable.Range(1, 100000).Select(i => $"Item {i}"));
}
public ObservableCollection<string> Items { get; }
public string SelectedItem { get; set; }
public void AddItem()
{
var index = SelectedItem != null ? Items.IndexOf(SelectedItem) : -1;
Items.Insert(index + 1, $"New Item {newItemIndex++}");
}
}
}

4
src/Avalonia.Controls/Repeater/ItemsRepeater.cs

@ -707,9 +707,9 @@ namespace Avalonia.Controls
}
}
private void InvalidateArrangeForLayout(object sender, EventArgs e) => InvalidateMeasure();
private void InvalidateMeasureForLayout(object sender, EventArgs e) => InvalidateMeasure();
private void InvalidateMeasureForLayout(object sender, EventArgs e) => InvalidateArrange();
private void InvalidateArrangeForLayout(object sender, EventArgs e) => InvalidateArrange();
private VirtualizingLayoutContext GetLayoutContext()
{

8
src/Avalonia.Controls/Repeater/ItemsSourceView.cs

@ -35,9 +35,11 @@ namespace Avalonia.Controls
{
Contract.Requires<ArgumentNullException>(source != null);
_inner = source as IList;
if (_inner == null && source is IEnumerable<object> objectEnumerable)
if (source is IList list)
{
_inner = list;
}
else if (source is IEnumerable<object> objectEnumerable)
{
_inner = new List<object>(objectEnumerable);
}

6
src/Avalonia.Layout/UniformGridLayoutState.cs

@ -72,12 +72,6 @@ namespace Avalonia.Layout
_cachedFirstElement.Measure(availableSize);
// This doesn't need to be done in the UWP version and I'm not sure why. If we
// don't do this here, and we receive a recycled element then it will be shown
// at its previous arrange point, but we don't want it shown at all until its
// arranged.
_cachedFirstElement.Arrange(new Rect(-10000.0, -10000.0, 0, 0));
SetSize(_cachedFirstElement, layoutItemWidth, LayoutItemHeight, availableSize, stretch, orientation, minRowSpacing, minColumnSpacing);
// See if we can move ownership to the flow algorithm. If we can, we do not need a local cache.

Loading…
Cancel
Save