Browse Source

Merge branch 'master' into fixes/2821-remove-contentcontrolmixin

pull/2926/head
danwalmsley 7 years ago
committed by GitHub
parent
commit
365cde4cc0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      samples/ControlCatalog/Pages/ListBoxPage.xaml
  2. 21
      samples/ControlCatalog/Pages/ListBoxPage.xaml.cs
  3. 10
      src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
  4. 12
      src/Avalonia.Input/InputElement.cs
  5. 27
      tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs

4
samples/ControlCatalog/Pages/ListBoxPage.xaml

@ -10,12 +10,14 @@
HorizontalAlignment="Center" HorizontalAlignment="Center"
Spacing="16"> Spacing="16">
<StackPanel Orientation="Vertical" Spacing="8"> <StackPanel Orientation="Vertical" Spacing="8">
<ListBox Items="{Binding Items}" SelectedItems="{Binding SelectedItems}" SelectionMode="{Binding SelectionMode}" Width="250" Height="350"></ListBox> <ListBox Items="{Binding Items}" SelectedItem="{Binding SelectedItem}" AutoScrollToSelectedItem="True" SelectedItems="{Binding SelectedItems}" SelectionMode="{Binding SelectionMode}" Width="250" Height="350"></ListBox>
<Button Command="{Binding AddItemCommand}">Add</Button> <Button Command="{Binding AddItemCommand}">Add</Button>
<Button Command="{Binding RemoveItemCommand}">Remove</Button> <Button Command="{Binding RemoveItemCommand}">Remove</Button>
<Button Command="{Binding SelectRandomItemCommand}">Select Random Item</Button>
<ComboBox SelectedIndex="{Binding SelectionMode, Mode=TwoWay}"> <ComboBox SelectedIndex="{Binding SelectionMode, Mode=TwoWay}">
<ComboBoxItem>Single</ComboBoxItem> <ComboBoxItem>Single</ComboBoxItem>
<ComboBoxItem>Multiple</ComboBoxItem> <ComboBoxItem>Multiple</ComboBoxItem>

21
samples/ControlCatalog/Pages/ListBoxPage.xaml.cs

@ -1,3 +1,4 @@
using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Reactive; using System.Reactive;
@ -27,7 +28,7 @@ namespace ControlCatalog.Pages
public PageViewModel() public PageViewModel()
{ {
Items = new ObservableCollection<string>(Enumerable.Range(1, 10).Select(i => GenerateItem())); Items = new ObservableCollection<string>(Enumerable.Range(1, 10000).Select(i => GenerateItem()));
SelectedItems = new ObservableCollection<string>(); SelectedItems = new ObservableCollection<string>();
AddItemCommand = ReactiveCommand.Create(() => Items.Add(GenerateItem())); AddItemCommand = ReactiveCommand.Create(() => Items.Add(GenerateItem()));
@ -39,16 +40,34 @@ namespace ControlCatalog.Pages
Items.Remove(SelectedItems[0]); Items.Remove(SelectedItems[0]);
} }
}); });
SelectRandomItemCommand = ReactiveCommand.Create(() =>
{
var random = new Random();
SelectedItem = Items[random.Next(Items.Count - 1)];
});
} }
public ObservableCollection<string> Items { get; } public ObservableCollection<string> Items { get; }
private string _selectedItem;
public string SelectedItem
{
get { return _selectedItem; }
set { this.RaiseAndSetIfChanged(ref _selectedItem, value); }
}
public ObservableCollection<string> SelectedItems { get; } public ObservableCollection<string> SelectedItems { get; }
public ReactiveCommand<Unit, Unit> AddItemCommand { get; } public ReactiveCommand<Unit, Unit> AddItemCommand { get; }
public ReactiveCommand<Unit, Unit> RemoveItemCommand { get; } public ReactiveCommand<Unit, Unit> RemoveItemCommand { get; }
public ReactiveCommand<Unit, Unit> SelectRandomItemCommand { get; }
public SelectionMode SelectionMode public SelectionMode SelectionMode
{ {
get => _selectionMode; get => _selectionMode;

10
src/Avalonia.Controls/Primitives/SelectingItemsControl.cs

@ -855,11 +855,6 @@ namespace Avalonia.Controls.Primitives
_selectedItem = ElementAt(Items, _selectedIndex); _selectedItem = ElementAt(Items, _selectedIndex);
RaisePropertyChanged(SelectedIndexProperty, -1, _selectedIndex, BindingPriority.LocalValue); RaisePropertyChanged(SelectedIndexProperty, -1, _selectedIndex, BindingPriority.LocalValue);
RaisePropertyChanged(SelectedItemProperty, null, _selectedItem, BindingPriority.LocalValue); RaisePropertyChanged(SelectedItemProperty, null, _selectedItem, BindingPriority.LocalValue);
if (AutoScrollToSelectedItem)
{
ScrollIntoView(_selectedIndex);
}
} }
} }
@ -1046,6 +1041,11 @@ namespace Avalonia.Controls.Primitives
removed?.Select(x => ElementAt(Items, x)).ToArray() ?? Array.Empty<object>()); removed?.Select(x => ElementAt(Items, x)).ToArray() ?? Array.Empty<object>());
RaiseEvent(e); RaiseEvent(e);
} }
if (AutoScrollToSelectedItem)
{
ScrollIntoView(_selectedItem);
}
} }
private void UpdateSelectedItems(Action action) private void UpdateSelectedItems(Action action)

12
src/Avalonia.Input/InputElement.cs

@ -565,9 +565,17 @@ namespace Avalonia.Input
{ {
IsEffectivelyEnabled = IsEnabledCore && (parent?.IsEffectivelyEnabled ?? true); IsEffectivelyEnabled = IsEnabledCore && (parent?.IsEffectivelyEnabled ?? true);
foreach (var child in this.GetVisualChildren().OfType<InputElement>()) // PERF-SENSITIVE: This is called on entire hierarchy and using foreach or LINQ
// will cause extra allocations and overhead.
var children = VisualChildren;
// ReSharper disable once ForCanBeConvertedToForeach
for (int i = 0; i < children.Count; ++i)
{ {
child.UpdateIsEffectivelyEnabled(this); var child = children[i] as InputElement;
child?.UpdateIsEffectivelyEnabled(this);
} }
} }
} }

27
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs

@ -894,6 +894,33 @@ namespace Avalonia.Controls.UnitTests.Primitives
Assert.Equal("Qux", target.SelectedItem); Assert.Equal("Qux", target.SelectedItem);
} }
[Fact]
public void AutoScrollToSelectedItem_Causes_Scroll_To_SelectedItem()
{
var items = new ObservableCollection<string>
{
"Foo",
"Bar",
"Baz"
};
var target = new ListBox
{
Template = Template(),
Items = items,
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
var raised = false;
target.AddHandler(Control.RequestBringIntoViewEvent, (s, e) => raised = true);
target.SelectedIndex = 2;
Assert.True(raised);
}
private FuncControlTemplate Template() private FuncControlTemplate Template()
{ {
return new FuncControlTemplate<SelectingItemsControl>((control, scope) => return new FuncControlTemplate<SelectingItemsControl>((control, scope) =>

Loading…
Cancel
Save