|
|
@@ -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();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|