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

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

@ -1,8 +1,11 @@
using System;
using System.Linq; using System.Linq;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using ControlCatalog.ViewModels;
namespace ControlCatalog.Pages namespace ControlCatalog.Pages
{ {
@ -16,7 +19,8 @@ namespace ControlCatalog.Pages
this.InitializeComponent(); this.InitializeComponent();
_repeater = this.FindControl<ItemsRepeater>("repeater"); _repeater = this.FindControl<ItemsRepeater>("repeater");
_scroller = this.FindControl<ScrollViewer>("scroller"); _scroller = this.FindControl<ScrollViewer>("scroller");
DataContext = Enumerable.Range(1, 100000).Select(i => $"Item {i}" ).ToArray(); _repeater.PointerPressed += RepeaterClick;
DataContext = new ItemsRepeaterPageViewModel();
} }
private void InitializeComponent() private void InitializeComponent()
@ -67,5 +71,11 @@ namespace ControlCatalog.Pages
break; 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() private VirtualizingLayoutContext GetLayoutContext()
{ {

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

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

6
src/Avalonia.Layout/UniformGridLayoutState.cs

@ -72,12 +72,6 @@ namespace Avalonia.Layout
_cachedFirstElement.Measure(availableSize); _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); 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. // See if we can move ownership to the flow algorithm. If we can, we do not need a local cache.

Loading…
Cancel
Save