@@ -1223,13 +1223,15 @@ public async Task ShowToolbar_Ok()
12231223 Assert . Contains ( "test-toolbar-template" , cut . Markup ) ;
12241224 }
12251225
1226+ #region DraggableTest
1227+
12261228 [ Fact ]
12271229 public async Task Draggable_Basic_MoveAsLastChild ( )
12281230 {
12291231 // Arrange
12301232 var items = new List < TreeFoo >
12311233 {
1232- new ( ) { Text = "Root " , Id = "1" } ,
1234+ new ( ) { Text = "Root1 " , Id = "1" } ,
12331235 new ( ) { Text = "Child1" , Id = "2" , ParentId = "1" } ,
12341236 new ( ) { Text = "Child2" , Id = "3" , ParentId = "1" } ,
12351237 new ( ) { Text = "Root2" , Id = "4" } ,
@@ -1245,37 +1247,39 @@ public async Task Draggable_Basic_MoveAsLastChild()
12451247
12461248 var rows = cut . FindComponents < TreeViewRow < TreeFoo > > ( ) ;
12471249 var dragSource = rows [ 1 ] ; // Child1
1248- var dragTarget = rows [ 3 ] ; // Root2
1250+ var dropTarget = rows [ 3 ] ; // Root2
12491251
1250- var dragSourceElement = dragSource . Find ( ".tree-node" ) ;
1251- var dragTargetDropZone = dragTarget . Find ( ".tree-drop-child-inside" ) ;
1252- // 1. 触发 dragstart
1253- await dragSourceElement . TriggerEventAsync ( "ondragstart" , new DragEventArgs ( ) ) ;
1254- // 2. 触发 dragenter 到目标 drop zone
1255- await dragTargetDropZone . TriggerEventAsync ( "ondragenter" , new DragEventArgs ( ) ) ;
1256- // 3. 触发 drop 到目标 drop zone
1257- await dragTargetDropZone . TriggerEventAsync ( "ondrop" , new DragEventArgs ( ) ) ;
1258- // 成功移动,原对象销毁,不触发dragend
1252+ var sourceElement = dragSource . Find ( ".tree-node" ) ;
1253+ // 拖动到节点中间的区域
1254+ var targetDropZone = dropTarget . Find ( ".tree-drop-child-inside" ) ;
1255+
1256+ await sourceElement . TriggerEventAsync ( "ondragstart" , new DragEventArgs ( ) ) ;
1257+ await targetDropZone . TriggerEventAsync ( "ondragenter" , new DragEventArgs ( ) ) ;
1258+ await targetDropZone . TriggerEventAsync ( "ondrop" , new DragEventArgs ( ) ) ;
12591259
12601260 // Assert
1261- Assert . Equal ( "Root2" , nodes [ 1 ] . Text ) ;
1262- Assert . Equal ( 2 , nodes [ 1 ] . Items . Count ) ;
1263- Assert . Equal ( "Child1" , nodes [ 1 ] . Items [ 1 ] . Text ) ;
1264- Assert . Equal ( nodes [ 1 ] , nodes [ 1 ] . Items [ 1 ] . Parent ) ;
1261+ Assert . Single ( nodes [ 0 ] . Items ) ; // Root1 只剩下 Child2
1262+ Assert . Equal ( 2 , nodes [ 1 ] . Items . Count ) ; // Root2 有 Child3 和 Child1
1263+ Assert . Equal ( "Child1" , nodes [ 1 ] . Items [ 1 ] . Text ) ; // Child1 成为 Root2 的最后一个子节点
1264+ Assert . Equal ( nodes [ 1 ] , nodes [ 1 ] . Items [ 1 ] . Parent ) ; // Child1 的父节点是 Root2
12651265 }
12661266
12671267 [ Fact ]
1268- public async Task Draggable_Basic_MoveAsSiblingBelow ( )
1268+ public async Task Draggable_Basic_MoveAsFirstChild ( )
12691269 {
12701270 // Arrange
12711271 var items = new List < TreeFoo >
12721272 {
1273- new ( ) { Text = "Root " , Id = "1" } ,
1273+ new ( ) { Text = "Root1 " , Id = "1" } ,
12741274 new ( ) { Text = "Child1" , Id = "2" , ParentId = "1" } ,
1275- new ( ) { Text = "Child2" , Id = "3" , ParentId = "1" }
1275+ new ( ) { Text = "Child2" , Id = "3" , ParentId = "1" } ,
1276+ new ( ) { Text = "Root2" , Id = "4" } ,
1277+ new ( ) { Text = "Child3" , Id = "5" , ParentId = "4" }
12761278 } ;
12771279 var nodes = TreeFoo . CascadingTree ( items ) ;
12781280 nodes [ 0 ] . IsExpand = true ;
1281+ // 展开情况才能作为第一个子节点进行拖入
1282+ nodes [ 1 ] . IsExpand = true ;
12791283 var cut = Context . RenderComponent < TreeView < TreeFoo > > ( pb =>
12801284 {
12811285 pb . Add ( a => a . Items , nodes ) ;
@@ -1284,24 +1288,106 @@ public async Task Draggable_Basic_MoveAsSiblingBelow()
12841288
12851289 var rows = cut . FindComponents < TreeViewRow < TreeFoo > > ( ) ;
12861290 var dragSource = rows [ 1 ] ; // Child1
1287- var dragTarget = rows [ 2 ] ; // Child2
1291+ var dragTarget = rows [ 3 ] ; // Root2
12881292
1289- // 获取可拖拽的 DOM 元素(DynamicElement)
1290- var dragSourceElement = dragSource . Find ( ".tree-node" ) ;
1291- var dragTargetDropZone = dragTarget . Find ( ".tree-drop-child-below" ) ;
1292- // 1. 触发 dragstart
1293- await dragSourceElement . TriggerEventAsync ( "ondragstart" , new DragEventArgs ( ) ) ;
1294- // 2. 触发 dragenter 到目标 drop zone
1295- await dragTargetDropZone . TriggerEventAsync ( "ondragenter" , new DragEventArgs ( ) ) ;
1296- // 3. 触发 drop 到目标 drop zone
1297- await dragTargetDropZone . TriggerEventAsync ( "ondrop" , new DragEventArgs ( ) ) ;
1298- // 成功移动,原对象销毁,不触发dragend
1293+ var sourceElement = dragSource . Find ( ".tree-node" ) ;
1294+ // 拖动到节点靠下的区域
1295+ var targetDropZone = dragTarget . Find ( ".tree-drop-child-below" ) ;
1296+
1297+ await sourceElement . TriggerEventAsync ( "ondragstart" , new DragEventArgs ( ) ) ;
1298+ await targetDropZone . TriggerEventAsync ( "ondragenter" , new DragEventArgs ( ) ) ;
1299+ await targetDropZone . TriggerEventAsync ( "ondrop" , new DragEventArgs ( ) ) ;
12991300
13001301 // Assert
1301- var parent = nodes [ 0 ] ;
1302- Assert . Equal ( 2 , parent . Items . Count ) ;
1303- Assert . Equal ( "Child2" , parent . Items [ 0 ] . Text ) ;
1304- Assert . Equal ( "Child1" , parent . Items [ 1 ] . Text ) ;
1302+ Assert . Single ( nodes [ 0 ] . Items ) ; // Root1 只剩下 Child2
1303+ Assert . Equal ( 2 , nodes [ 1 ] . Items . Count ) ; // Root2 有 Child1 和 Child3
1304+ Assert . Equal ( "Child1" , nodes [ 1 ] . Items [ 0 ] . Text ) ; // Child1 成为 Root2 的第一个子节点
1305+ Assert . Equal ( nodes [ 1 ] , nodes [ 1 ] . Items [ 0 ] . Parent ) ; // Child1 的父节点是 Root2
1306+ }
1307+
1308+ [ Fact ]
1309+ public async Task Draggable_Basic_MoveAsSiblingBelow ( )
1310+ {
1311+ // Arrange
1312+ var items = new List < TreeFoo >
1313+ {
1314+ new ( ) { Text = "Root1" , Id = "1" } ,
1315+ new ( ) { Text = "Child1" , Id = "2" , ParentId = "1" } ,
1316+ new ( ) { Text = "Child2" , Id = "3" , ParentId = "1" } ,
1317+ new ( ) { Text = "Root2" , Id = "4" } ,
1318+ new ( ) { Text = "Child3" , Id = "5" , ParentId = "4" } ,
1319+ new ( ) { Text = "Child4" , Id = "6" , ParentId = "4" } ,
1320+ new ( ) { Text = "Root3" , Id = "7" }
1321+ } ;
1322+ var nodes = TreeFoo . CascadingTree ( items ) ;
1323+ nodes [ 0 ] . IsExpand = true ;
1324+ nodes [ 1 ] . IsExpand = true ;
1325+ var cut = Context . RenderComponent < TreeView < TreeFoo > > ( pb =>
1326+ {
1327+ pb . Add ( a => a . Items , nodes ) ;
1328+ pb . Add ( a => a . ItemDraggable , true ) ;
1329+ } ) ;
1330+
1331+ var rowsA = cut . FindComponents < TreeViewRow < TreeFoo > > ( ) ;
1332+ var source1 = rowsA [ 1 ] ; // Child1
1333+ var target1 = rowsA [ 4 ] ; // Child3
1334+
1335+ var drag1 = source1 . Find ( ".tree-node" ) ;
1336+ // 拖动到 Child3 的下方,非最后一个兄弟节点
1337+ var drop1 = target1 . Find ( ".tree-drop-child-below" ) ;
1338+
1339+ await drag1 . TriggerEventAsync ( "ondragstart" , new DragEventArgs ( ) ) ;
1340+ await drop1 . TriggerEventAsync ( "ondragenter" , new DragEventArgs ( ) ) ;
1341+ await drop1 . TriggerEventAsync ( "ondrop" , new DragEventArgs ( ) ) ;
1342+
1343+ // Assert
1344+ Assert . Single ( nodes [ 0 ] . Items ) ; // Root1 只剩下 Child2
1345+ Assert . Equal ( 3 , nodes [ 1 ] . Items . Count ) ; // Root2 有 Child3, Child1 和 Child4
1346+ Assert . Equal ( "Child3" , nodes [ 1 ] . Items [ 0 ] . Text ) ;
1347+ Assert . Equal ( "Child1" , nodes [ 1 ] . Items [ 1 ] . Text ) ; // Child1 成为 Child3 的下一个兄弟节点
1348+
1349+ // 渲染变更后的内容
1350+ cut . Render ( ) ;
1351+
1352+ var rowsB = cut . FindComponents < TreeViewRow < TreeFoo > > ( ) ;
1353+ var source2 = rowsB [ 1 ] ; // Child2
1354+ var target2 = rowsB [ 5 ] ; // Child4
1355+
1356+ var drag2 = source2 . Find ( ".tree-node" ) ;
1357+ // 拖动到 Child4 的下方,成为最后一个兄弟节点
1358+ var drop2 = target2 . Find ( ".tree-drop-child-below" ) ;
1359+
1360+ await drag2 . TriggerEventAsync ( "ondragstart" , new DragEventArgs ( ) ) ;
1361+ await drop2 . TriggerEventAsync ( "ondragenter" , new DragEventArgs ( ) ) ;
1362+ await drop2 . TriggerEventAsync ( "ondrop" , new DragEventArgs ( ) ) ;
1363+
1364+ // Assert
1365+ Assert . Empty ( nodes [ 0 ] . Items ) ; // Root1 没有对象
1366+ Assert . Equal ( 4 , nodes [ 1 ] . Items . Count ) ; // Root2 有 Child3, Child1, Child4 和 Child2
1367+ Assert . Equal ( "Child3" , nodes [ 1 ] . Items [ 0 ] . Text ) ;
1368+ Assert . Equal ( "Child1" , nodes [ 1 ] . Items [ 1 ] . Text ) ; // Child1 仍然是 Child3 的下一个兄弟节点
1369+ Assert . Equal ( "Child4" , nodes [ 1 ] . Items [ 2 ] . Text ) ; // Child4 仍然是 Child1 的下一个兄弟节点
1370+ Assert . Equal ( "Child2" , nodes [ 1 ] . Items [ 3 ] . Text ) ; // Child2 成为最后一个兄弟节点
1371+
1372+ // 渲染变更后的内容
1373+ cut . Render ( ) ;
1374+
1375+ var rowsC = cut . FindComponents < TreeViewRow < TreeFoo > > ( ) ;
1376+ var source3 = rowsC [ 0 ] ; // Root1
1377+ var target3 = rowsC [ 6 ] ; // Root3
1378+
1379+ var drag3 = source3 . Find ( ".tree-node" ) ;
1380+ // 拖动到 Root 的下方,成为根节点,且为最后一个兄弟节点
1381+ var drop3 = target3 . Find ( ".tree-drop-child-below" ) ;
1382+
1383+ await drag3 . TriggerEventAsync ( "ondragstart" , new DragEventArgs ( ) ) ;
1384+ await drop3 . TriggerEventAsync ( "ondragenter" , new DragEventArgs ( ) ) ;
1385+ await drop3 . TriggerEventAsync ( "ondrop" , new DragEventArgs ( ) ) ;
1386+
1387+ // Assert
1388+ Assert . Equal ( 3 , nodes . Count ) ;
1389+ Assert . Equal ( "Root2" , nodes [ 0 ] . Text ) ;
1390+ Assert . Equal ( "Root1" , nodes [ 2 ] . Text ) ; // Root1 成为最后一个根节点
13051391 }
13061392
13071393 [ Fact ]
@@ -1375,6 +1461,8 @@ public async Task Draggable_DragClassState()
13751461 Assert . DoesNotContain ( "tree-drop-pass" , row . Markup ) ;
13761462 }
13771463
1464+ #endregion
1465+
13781466 class MockTree < TItem > : TreeView < TItem > where TItem : class
13791467 {
13801468 public bool TestComparerItem ( TItem ? a , TItem ? b ) => base . Equals ( a , b ) ;
0 commit comments