Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: add VirtualizingGridPanel #2143

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
110 changes: 87 additions & 23 deletions samples/VirtualizationDemo/MainWindow.xaml
@@ -1,10 +1,14 @@
<Window xmlns="https://github.com/avaloniaui"
Title="AvaloniaUI Virtualization Test"
Width="800"
Height="600">
<DockPanel LastChildFill="True" Margin="16">
<StackPanel DockPanel.Dock="Right"
Margin="16 0 0 0"
Height="600"
MinWidth="50" MinHeight="200">
<TabControl>
<TabItem Header="StackPanel" >

<DockPanel LastChildFill="True" Margin="16" DataContext="{Binding StackPanelVM}">
<StackPanel DockPanel.Dock="Right"
Margin="16 0 0 0"
MinWidth="150"
Spacing="4">
<DropDown Items="{Binding VirtualizationModes}"
Expand Down Expand Up @@ -39,23 +43,83 @@
<Button Command="{Binding SelectLastCommand}">Select Last</Button>
</StackPanel>

<ListBox Name="listBox"
Items="{Binding Items}"
SelectedItems="{Binding SelectedItems}"
SelectionMode="Multiple"
VirtualizationMode="{Binding VirtualizationMode}"
ScrollViewer.HorizontalScrollBarVisibility="{Binding HorizontalScrollBarVisibility, Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="{Binding VerticalScrollBarVisibility, Mode=TwoWay}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="{Binding Orientation}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}" TextWrapping="Wrap"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Name="listBox"
Items="{Binding Items}"
SelectedItems="{Binding SelectedItems}"
SelectionMode="Multiple"
VirtualizationMode="{Binding VirtualizationMode}"
ScrollViewer.HorizontalScrollBarVisibility="{Binding HorizontalScrollBarVisibility, Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="{Binding VerticalScrollBarVisibility, Mode=TwoWay}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="{Binding Orientation}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}" TextWrapping="Wrap" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

</DockPanel>
</Window>
</TabItem>
<TabItem Header="GridPanel" >
<DockPanel LastChildFill="True" Margin="16" DataContext="{Binding GridPanelVM}">
<StackPanel DockPanel.Dock="Right"
Margin="16 0 0 0"
MinWidth="150"
Spacing="4">
<DropDown Items="{Binding VirtualizationModes}"
SelectedItem="{Binding VirtualizationMode}"/>
<DropDown Items="{Binding Orientations}"
SelectedItem="{Binding Orientation}"/>
<TextBox Watermark="Item Count"
UseFloatingWatermark="True"
Text="{Binding ItemCount}"/>
<TextBox Watermark="Extent"
UseFloatingWatermark="True"
Text="{Binding #listBoxGrid.Scroll.Extent, Mode=OneWay}"/>
<TextBox Watermark="Offset"
UseFloatingWatermark="True"
Text="{Binding #listBoxGrid.Scroll.Offset, Mode=OneWay}"/>
<TextBox Watermark="Viewport"
UseFloatingWatermark="True"
Text="{Binding #listBoxGrid.Scroll.Viewport, Mode=OneWay}"/>
<TextBlock>Horiz. ScrollBar</TextBlock>
<DropDown Items="{Binding ScrollBarVisibilities}"
SelectedItem="{Binding HorizontalScrollBarVisibility}"/>
<TextBlock>Vert. ScrollBar</TextBlock>
<DropDown Items="{Binding ScrollBarVisibilities}"
SelectedItem="{Binding VerticalScrollBarVisibility}"/>
<TextBox Watermark="Item to Create"
UseFloatingWatermark="True"
Text="{Binding NewItemString}"/>
<Button Command="{Binding AddItemCommand}">Add Item</Button>
<Button Command="{Binding RemoveItemCommand}">Remove Item</Button>
<Button Command="{Binding RecreateCommand}">Recreate</Button>
<Button Command="{Binding SelectFirstCommand}">Select First</Button>
<Button Command="{Binding SelectLastCommand}">Select Last</Button>
</StackPanel>
<ListBox Name="listBoxGrid"
Items="{Binding Items}"
SelectedItems="{Binding SelectedItems}"
SelectionMode="Multiple"
VirtualizationMode="{Binding VirtualizationMode}"
ScrollViewer.HorizontalScrollBarVisibility="{Binding HorizontalScrollBarVisibility, Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="{Binding VerticalScrollBarVisibility, Mode=TwoWay}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingGridPanel ItemWidth="100" ItemHeight="30" Orientation="{Binding Orientation}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}" TextWrapping="Wrap" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</TabItem>
</TabControl>
</Window>
16 changes: 8 additions & 8 deletions samples/VirtualizationDemo/Program.cs
Expand Up @@ -11,13 +11,13 @@ namespace VirtualizationDemo
{
class Program
{
static void Main(string[] args)
{
AppBuilder.Configure<App>()
.UsePlatformDetect()
.UseReactiveUI()
.LogToDebug()
.Start<MainWindow>();
}
static void Main(string[] args) => BuildAvaloniaApp().Start<MainWindow>();

// App configuration, used by the entry point and previewer
static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.UseReactiveUI()
.LogToDebug();
}
}
1 change: 1 addition & 0 deletions samples/VirtualizationDemo/ViewModels/ItemViewModel.cs
Expand Up @@ -18,5 +18,6 @@ public ItemViewModel(int index, string prefix = "Item")
}

public string Header => $"{_prefix} {_index}";
public double Height => _index%6*40+10 ;
}
}
139 changes: 6 additions & 133 deletions samples/VirtualizationDemo/ViewModels/MainWindowViewModel.cs
Expand Up @@ -14,142 +14,15 @@ namespace VirtualizationDemo.ViewModels
{
internal class MainWindowViewModel : ReactiveObject
{
private int _itemCount = 200;
private string _newItemString = "New Item";
private int _newItemIndex;
private IReactiveList<ItemViewModel> _items;
private string _prefix = "Item";
private ScrollBarVisibility _horizontalScrollBarVisibility = ScrollBarVisibility.Auto;
private ScrollBarVisibility _verticalScrollBarVisibility = ScrollBarVisibility.Auto;
private Orientation _orientation = Orientation.Vertical;
private ItemVirtualizationMode _virtualizationMode = ItemVirtualizationMode.Simple;

public MainWindowViewModel()
{
this.WhenAnyValue(x => x.ItemCount).Subscribe(ResizeItems);
RecreateCommand = ReactiveCommand.Create(() => Recreate());

AddItemCommand = ReactiveCommand.Create(() => AddItem());

RemoveItemCommand = ReactiveCommand.Create(() => Remove());

SelectFirstCommand = ReactiveCommand.Create(() => SelectItem(0));

SelectLastCommand = ReactiveCommand.Create(() => SelectItem(Items.Count - 1));
}

public string NewItemString
{
get { return _newItemString; }
set { this.RaiseAndSetIfChanged(ref _newItemString, value); }
}

public int ItemCount
{
get { return _itemCount; }
set { this.RaiseAndSetIfChanged(ref _itemCount, value); }
}

public AvaloniaList<ItemViewModel> SelectedItems { get; }
= new AvaloniaList<ItemViewModel>();

public IReactiveList<ItemViewModel> Items
{
get { return _items; }
private set { this.RaiseAndSetIfChanged(ref _items, value); }
}

public Orientation Orientation
{
get { return _orientation; }
set { this.RaiseAndSetIfChanged(ref _orientation, value); }
}

public IEnumerable<Orientation> Orientations =>
Enum.GetValues(typeof(Orientation)).Cast<Orientation>();

public ScrollBarVisibility HorizontalScrollBarVisibility
{
get { return _horizontalScrollBarVisibility; }
set { this.RaiseAndSetIfChanged(ref _horizontalScrollBarVisibility, value); }
}

public ScrollBarVisibility VerticalScrollBarVisibility
{
get { return _verticalScrollBarVisibility; }
set { this.RaiseAndSetIfChanged(ref _verticalScrollBarVisibility, value); }
}

public IEnumerable<ScrollBarVisibility> ScrollBarVisibilities =>
Enum.GetValues(typeof(ScrollBarVisibility)).Cast<ScrollBarVisibility>();

public ItemVirtualizationMode VirtualizationMode
{
get { return _virtualizationMode; }
set { this.RaiseAndSetIfChanged(ref _virtualizationMode, value); }
}

public IEnumerable<ItemVirtualizationMode> VirtualizationModes =>
Enum.GetValues(typeof(ItemVirtualizationMode)).Cast<ItemVirtualizationMode>();

public ReactiveCommand AddItemCommand { get; private set; }
public ReactiveCommand RecreateCommand { get; private set; }
public ReactiveCommand RemoveItemCommand { get; private set; }
public ReactiveCommand SelectFirstCommand { get; private set; }
public ReactiveCommand SelectLastCommand { get; private set; }

private void ResizeItems(int count)
{
if (Items == null)
{
var items = Enumerable.Range(0, count)
.Select(x => new ItemViewModel(x));
Items = new ReactiveList<ItemViewModel>(items);
}
else if (count > Items.Count)
{
var items = Enumerable.Range(Items.Count, count - Items.Count)
.Select(x => new ItemViewModel(x));
Items.AddRange(items);
}
else if (count < Items.Count)
{
Items.RemoveRange(count, Items.Count - count);
}
}

private void AddItem()
{
var index = Items.Count;

if (SelectedItems.Count > 0)
{
index = Items.IndexOf(SelectedItems[0]);
}

Items.Insert(index, new ItemViewModel(_newItemIndex++, NewItemString));
}

private void Remove()
{
if (SelectedItems.Count > 0)
{
Items.RemoveAll(SelectedItems);
}
}

private void Recreate()
{
_prefix = _prefix == "Item" ? "Recreated" : "Item";
var items = Enumerable.Range(0, _itemCount)
.Select(x => new ItemViewModel(x, _prefix));
Items = new ReactiveList<ItemViewModel>(items);
}

private void SelectItem(int index)
{
SelectedItems.Clear();
SelectedItems.Add(Items[index]);
StackPanelVM = new VirtualizationViewModel();
GridPanelVM = new VirtualizationViewModel() {
HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
Orientation = Orientation.Horizontal };
}
public VirtualizationViewModel StackPanelVM{ get; set; }
public VirtualizationViewModel GridPanelVM{ get; set; }
}
}