@@ -245,6 +245,12 @@ public partial class TreeView<TItem> : IModelEqualityComparer<TItem>
245
245
[ Parameter ]
246
246
public string ? ExpandNodeIcon { get ; set ; }
247
247
248
+ /// <summary>
249
+ /// 获得/设置 是否开启键盘上下键操作 默认 false
250
+ /// </summary>
251
+ [ Parameter ]
252
+ public bool EnableKeyboardArrowUpDown { get ; set ; }
253
+
248
254
[ CascadingParameter ]
249
255
private ContextMenuZone ? ContextMenuZone { get ; set ; }
250
256
@@ -283,6 +289,8 @@ public partial class TreeView<TItem> : IModelEqualityComparer<TItem>
283
289
284
290
private string ? _searchText ;
285
291
292
+ private string ? EnableKeyboardArrowUpDownString => EnableKeyboardArrowUpDown ? "true" : null ;
293
+
286
294
/// <summary>
287
295
/// <inheritdoc/>
288
296
/// </summary>
@@ -346,6 +354,91 @@ protected override async Task OnParametersSetAsync()
346
354
}
347
355
}
348
356
357
+ /// <summary>
358
+ /// <inheritdoc/>
359
+ /// </summary>
360
+ /// <returns></returns>
361
+ protected override Task InvokeInitAsync ( ) => InvokeVoidAsync ( "init" , Id , Interop , nameof ( TriggerKeyDown ) ) ;
362
+
363
+ /// <summary>
364
+ /// 客户端用户键盘操作处理方法 由 JavaScript 调用
365
+ /// </summary>
366
+ /// <param name="key"></param>
367
+ /// <returns></returns>
368
+ [ JSInvokable ]
369
+ public async ValueTask TriggerKeyDown ( string key )
370
+ {
371
+ // 通过 ActiveItem 找到兄弟节点
372
+ // 如果兄弟节点没有时,找到父亲节点
373
+ if ( ActiveItem != null )
374
+ {
375
+ await ActiveTreeViewItem ( key , ActiveItem ) ;
376
+ StateHasChanged ( ) ;
377
+ }
378
+ }
379
+
380
+ private static bool IsExpand ( TreeViewItem < TItem > item ) => item . IsExpand && item . Items . Count > 0 ;
381
+
382
+ private List < TreeViewItem < TItem > > GetItems ( TreeViewItem < TItem > item ) => item . Parent ? . Items ?? Items ;
383
+
384
+ private async Task ActiveTreeViewItem ( string key , TreeViewItem < TItem > item )
385
+ {
386
+ var items = GetItems ( item ) ;
387
+ var index = items . IndexOf ( item ) ;
388
+
389
+ if ( key == "ArrowUp" )
390
+ {
391
+ index -- ;
392
+ if ( index >= 0 )
393
+ {
394
+ var currentItem = items [ index ] ;
395
+ if ( IsExpand ( currentItem ) )
396
+ {
397
+ await OnClick ( currentItem . Items [ ^ 1 ] ) ;
398
+ }
399
+ else
400
+ {
401
+ await OnClick ( currentItem ) ;
402
+ }
403
+ }
404
+ else if ( item . Parent != null )
405
+ {
406
+ await OnClick ( item . Parent ) ;
407
+ }
408
+ }
409
+ else if ( key == "ArrowDown" )
410
+ {
411
+ if ( IsExpand ( item ) )
412
+ {
413
+ await OnClick ( item . Items [ 0 ] ) ;
414
+ }
415
+ else
416
+ {
417
+ index ++ ;
418
+ if ( index < items . Count )
419
+ {
420
+ await OnClick ( items [ index ] ) ;
421
+ }
422
+ else if ( item . Parent != null )
423
+ {
424
+ await ActiveParentTreeViewItem ( item . Parent ) ;
425
+ }
426
+ }
427
+ }
428
+ }
429
+
430
+ private async Task ActiveParentTreeViewItem ( TreeViewItem < TItem > item )
431
+ {
432
+ var items = GetItems ( item ) ;
433
+ var index = items . IndexOf ( item ) ;
434
+
435
+ index ++ ;
436
+ if ( index < items . Count )
437
+ {
438
+ await OnClick ( items [ index ] ) ;
439
+ }
440
+ }
441
+
349
442
private async Task < bool > OnBeforeStateChangedCallback ( TreeViewItem < TItem > item , CheckboxState state )
350
443
{
351
444
var ret = true ;
@@ -416,7 +509,7 @@ private async Task OnClick(TreeViewItem<TItem> item)
416
509
if ( ShowCheckbox && ClickToggleCheck )
417
510
{
418
511
item . CheckedState = ToggleCheckState ( item . CheckedState ) ;
419
- await OnCheckStateChanged ( item ) ;
512
+ await OnCheckStateChanged ( item , false ) ;
420
513
}
421
514
422
515
StateHasChanged ( ) ;
0 commit comments