|
|
|
@ -15,6 +15,7 @@ using Avalonia.Controls.Utils; |
|
|
|
using Avalonia.Input; |
|
|
|
using Avalonia.LogicalTree; |
|
|
|
using Avalonia.Metadata; |
|
|
|
using Avalonia.VisualTree; |
|
|
|
|
|
|
|
namespace Avalonia.Controls |
|
|
|
{ |
|
|
|
@ -323,35 +324,37 @@ namespace Avalonia.Controls |
|
|
|
LogicalChildren.RemoveAll(toRemove); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Handles directional navigation within the <see cref="ItemsControl"/>.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="e">The key events.</param>
|
|
|
|
protected override void OnKeyDown(KeyEventArgs e) |
|
|
|
{ |
|
|
|
if (Presenter?.Panel is INavigableContainer container) |
|
|
|
var focus = FocusManager.Instance; |
|
|
|
var direction = e.Key.ToNavigationDirection(); |
|
|
|
var container = Presenter?.Panel as INavigableContainer; |
|
|
|
|
|
|
|
if (container == null || |
|
|
|
focus.Current == null || |
|
|
|
direction == null || |
|
|
|
direction.Value.IsTab()) |
|
|
|
{ |
|
|
|
var focus = FocusManager.Instance; |
|
|
|
var current = focus.Current; |
|
|
|
NavigationDirection? direction = null; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
switch (e.Key) |
|
|
|
{ |
|
|
|
case Key.Up: direction = NavigationDirection.Up; break; |
|
|
|
case Key.Down: direction = NavigationDirection.Down; break; |
|
|
|
case Key.Left: direction = NavigationDirection.Left; break; |
|
|
|
case Key.Right: direction = NavigationDirection.Right; break; |
|
|
|
case Key.Home: direction = NavigationDirection.First; break; |
|
|
|
case Key.End: direction = NavigationDirection.Last; break; |
|
|
|
case Key.PageUp: direction = NavigationDirection.PageUp; break; |
|
|
|
case Key.PageDown: direction = NavigationDirection.PageDown; break; |
|
|
|
} |
|
|
|
var current = focus.Current |
|
|
|
.GetSelfAndVisualAncestors() |
|
|
|
.OfType<IInputElement>() |
|
|
|
.FirstOrDefault(x => x.VisualParent == container); |
|
|
|
|
|
|
|
if (direction != null && current != null) |
|
|
|
{ |
|
|
|
var next = container.GetControl(direction.Value, current); |
|
|
|
if (current != null) |
|
|
|
{ |
|
|
|
var next = container.GetControl(direction.Value, current); |
|
|
|
|
|
|
|
if (next != null) |
|
|
|
{ |
|
|
|
focus.Focus(next, NavigationMethod.Directional); |
|
|
|
e.Handled = true; |
|
|
|
} |
|
|
|
if (next != null) |
|
|
|
{ |
|
|
|
focus.Focus(next, NavigationMethod.Directional); |
|
|
|
e.Handled = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -370,6 +373,7 @@ namespace Avalonia.Controls |
|
|
|
var oldValue = e.OldValue as IEnumerable; |
|
|
|
var newValue = e.NewValue as IEnumerable; |
|
|
|
|
|
|
|
UpdateItemCount(); |
|
|
|
RemoveControlItemsFromLogicalChildren(oldValue); |
|
|
|
AddControlItemsToLogicalChildren(newValue); |
|
|
|
SubscribeToItems(newValue); |
|
|
|
@ -393,10 +397,8 @@ namespace Avalonia.Controls |
|
|
|
RemoveControlItemsFromLogicalChildren(e.OldItems); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
int? count = (Items as IList)?.Count; |
|
|
|
if (count != null) |
|
|
|
ItemCount = (int)count; |
|
|
|
|
|
|
|
UpdateItemCount(); |
|
|
|
|
|
|
|
var collection = sender as ICollection; |
|
|
|
PseudoClasses.Set(":empty", collection == null || collection.Count == 0); |
|
|
|
@ -480,5 +482,21 @@ namespace Avalonia.Controls |
|
|
|
// TODO: Rebuild the item containers.
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void UpdateItemCount() |
|
|
|
{ |
|
|
|
if (Items == null) |
|
|
|
{ |
|
|
|
ItemCount = 0; |
|
|
|
} |
|
|
|
else if (Items is IList list) |
|
|
|
{ |
|
|
|
ItemCount = list.Count; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
ItemCount = Items.Count(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|