Browse Source

Implement ItemsControl.IsTextSearchEnabled

pull/6210/head
Royce551 5 years ago
parent
commit
f2907c4f49
  1. 69
      src/Avalonia.Controls/ItemsControl.cs

69
src/Avalonia.Controls/ItemsControl.cs

@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using Avalonia.Collections;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Metadata;
@ -12,6 +13,7 @@ using Avalonia.Controls.Utils;
using Avalonia.Input;
using Avalonia.LogicalTree;
using Avalonia.Metadata;
using Avalonia.Threading;
using Avalonia.VisualTree;
namespace Avalonia.Controls
@ -52,6 +54,11 @@ namespace Avalonia.Controls
public static readonly StyledProperty<IDataTemplate> ItemTemplateProperty =
AvaloniaProperty.Register<ItemsControl, IDataTemplate>(nameof(ItemTemplate));
public static readonly StyledProperty<bool> IsTextSearchEnabledProperty =
AvaloniaProperty.Register<ItemsControl, bool>(nameof(IsTextSearchEnabled), true);
private string _textSearchTerm = string.Empty;
private DispatcherTimer _textSearchTimer;
private IEnumerable _items = new AvaloniaList<object>();
private int _itemCount;
private IItemContainerGenerator _itemContainerGenerator;
@ -135,6 +142,12 @@ namespace Avalonia.Controls
set { SetValue(ItemTemplateProperty, value); }
}
public bool IsTextSearchEnabled
{
get { return GetValue(IsTextSearchEnabledProperty); }
set { SetValue(IsTextSearchEnabledProperty, value); }
}
/// <summary>
/// Gets the items presenter control.
/// </summary>
@ -323,6 +336,36 @@ namespace Avalonia.Controls
base.OnKeyDown(e);
}
protected override void OnTextInput(TextInputEventArgs e)
{
if (!e.Handled && this is SelectingItemsControl selectingItemsControl)
{
if (!IsTextSearchEnabled)
return;
StopTextSearchTimer();
_textSearchTerm += e.Text;
bool match(ItemContainerInfo info) =>
info.ContainerControl is IContentControl control &&
control.Content?.ToString()?.StartsWith(_textSearchTerm, StringComparison.OrdinalIgnoreCase) == true;
var info = ItemContainerGenerator.Containers.FirstOrDefault(match);
if (info != null)
{
selectingItemsControl.SelectedIndex = info.Index;
}
StartTextSearchTimer();
e.Handled = true;
}
base.OnTextInput(e);
}
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change)
{
base.OnPropertyChanged(change);
@ -456,6 +499,32 @@ namespace Avalonia.Controls
}
}
private void StartTextSearchTimer()
{
_textSearchTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
_textSearchTimer.Tick += TextSearchTimer_Tick;
_textSearchTimer.Start();
}
private void StopTextSearchTimer()
{
if (_textSearchTimer == null)
{
return;
}
_textSearchTimer.Stop();
_textSearchTimer.Tick -= TextSearchTimer_Tick;
_textSearchTimer = null;
}
private void TextSearchTimer_Tick(object sender, EventArgs e)
{
_textSearchTerm = string.Empty;
StopTextSearchTimer();
}
private void UpdateItemCount()
{
if (Items == null)

Loading…
Cancel
Save