树节点移动操作----使用微软treeview控件[原创]
树节点移动操作
----使用微软treeview控件
作者:pfengk
MSN: pfengk@hotmail.com
更多文章请访问:http://www.cnblogs.com/pfengk/
目录
概述................................................................................................................................. 1
操作演示.......................................................................................................................... 1
实现源码:[C#]................................................................................................................ 2
概述
本文集中体现树节点移动实现代码其中很多其他代码省略。如果你对treeview控件不了解,请参阅我的另外一篇文章《web方式下权限分配简单实现》。
源码中引用命名空间Microsoft.Web.UI.WebControls。
本文描述节点移动算法效率非常低下,仅仅适合于节点不多的情况下使用。还请高手们多多指教。联系我的msn,谢谢你们!
操作演示
窗体载入初始界面
选择节点之后
点击[赋予]按钮之后
再次点击[赋予]按钮之后
实现源码:[C#]
1
#region "一棵树到另一棵树的 节点移动方法"
2
3
/// <summary>
4
5
/// 从parentTreeView(森林)的所有根节点中查找childTreeNode是否存在(使用Text属性为关键字比较),存在返回true.
6
7
/// </summary>
8
9
/// <param name="childTreeNode"></param>
10
11
/// <param name="parentTreeNode"></param>
12
13
/// <returns></returns>
14
15
public bool FindNodeFromChildNodes(TreeNode childTreeNode,TreeView parentTreeView)
16
17
{
18
19
bool returnValue = false;
20
21
22
23
foreach(TreeNode tempTreeNode in parentTreeView.Nodes)
24
25
{
26
27
if (childTreeNode.Text == tempTreeNode.Text)
28
29
{
30
31
returnValue = true;
32
33
break;
34
35
}
36
37
}
38
39
return returnValue;
40
41
}
42
43
44
45
/// <summary>
46
47
/// 从parentTreeView(森林)的所有根节点中查找childTreeNode是否存在(使用Text属性为关键字比较),存在返回true.
48
49
/// </summary>
50
51
/// <param name="childTreeNode"></param>
52
53
/// <param name="parentTreeNode"></param>
54
55
/// <returns></returns>
56
57
public bool FindNodeFromChildNodes(TreeNode childTreeNode,TreeView parentTreeView,ref TreeNode foundTreeNode)
58
59
{
60
61
bool returnValue = false;
62
63
64
65
foreach(TreeNode tempTreeNode in parentTreeView.Nodes)
66
67
{
68
69
if (childTreeNode.Text == tempTreeNode.Text)
70
71
{
72
73
returnValue = true;
74
75
foundTreeNode = tempTreeNode;
76
77
break;
78
79
}
80
81
}
82
83
return returnValue;
84
85
}
86
87
88
89
/// <summary>
90
91
/// 从parentTreeNode(根节点)的所有节点中查找childTreeNode是否存在(使用Text属性为关键字比较),存在返回true.
92
93
/// </summary>
94
95
/// <param name="childTreeNode"></param>
96
97
/// <param name="parentTreeNode"></param>
98
99
/// <returns></returns>
100
101
public bool FindNodeFromChildNodes(TreeNode childTreeNode,TreeNode parentTreeNode)
102
103
{
104
105
bool returnValue = false;
106
107
108
109
foreach(TreeNode tempTreeNode in parentTreeNode.Nodes)
110
111
{
112
113
if (childTreeNode.Text == tempTreeNode.Text)
114
115
{
116
117
returnValue = true;
118
119
break;
120
121
}
122
123
}
124
125
return returnValue;
126
127
}
128
129
130
131
/// <summary>
132
133
/// 从parentTreeView(森林)的所有根节点中查找childTreeNode是否存在(使用Text属性为关键字比较),存在返回true.
134
135
/// </summary>
136
137
/// <param name="childTreeNode"></param>
138
139
/// <param name="parentTreeNode"></param>
140
141
/// <returns></returns>
142
143
public bool FindNodeFromChildNodes(TreeNode childTreeNode,TreeNode parentTreeNode,ref TreeNode foundTreeNode)
144
145
{
146
147
bool returnValue = false;
148
149
150
151
foreach(TreeNode tempTreeNode in parentTreeNode.Nodes)
152
153
{
154
155
if (childTreeNode.Text == tempTreeNode.Text)
156
157
{
158
159
returnValue = true;
160
161
foundTreeNode = tempTreeNode;
162
163
break;
164
165
}
166
167
}
168
169
return returnValue;
170
171
}
172
173
174
175
/// <summary>
176
177
/// 移除叶子节点。首先判断是否为叶子节点或根节点,是则移除,否则跳出返回
178
179
/// </summary>
180
181
/// <param name="treeNode"></param>
182
183
/// <returns></returns>
184
185
public bool RemoveLeafageChildNode(ref TreeNode treeNode)
186
187
{
188
189
bool returnValue = false;
190
191
if (treeNode.Nodes == null | treeNode.Nodes.Count == 0)
192
193
{//是子节点时候
194
195
if (treeNode.Parent is TreeNode)
196
197
{//父节点为节点类型时
198
199
int nodesCount = ((TreeNode)treeNode.Parent).Nodes.Count;
200
201
if (nodesCount > 1)
202
203
{//还有兄弟叶子节点时候,仅仅删除本节点
204
205
treeNode.Remove();
206
207
returnValue = true;
208
209
}
210
211
else
212
213
{//是唯一叶子节点时候,还要删除父节点
214
215
//删除本节点
216
217
TreeNode thisParentTreeNode = (TreeNode)treeNode.Parent;
218
219
treeNode.Remove();
220
221
//删除父节点
222
223
returnValue = RemoveLeafageChildNode(ref thisParentTreeNode);
224
225
}
226
227
}
228
229
else
230
231
{//父节点不为节点类型时,他一定是根节点
232
233
treeNode.Remove();
234
235
returnValue = true;
236
237
}
238
239
}
240
241
return returnValue;
242
243
}
244
245
246
247
/// <summary>
248
249
/// 【MoveNodes】将节点分支中所有被选中的节点,移动到另外一个节点分支上。前提根节点必须保留,且各节点Text值唯一。
250
251
/// </summary>
252
253
/// <param name="fromTreeView"></param>
254
255
/// <param name="toTreeNode"></param>
256
257
public void MoveNodes(ref TreeNode fromTreeNode,ref TreeNode toTreeNode)
258
259
{
260
261
bool selected = true;
262
263
//遍历fromTreeNode子节点,比较选中子节点在toTreeNode的子节点集中是否存在,不存在则移动子节点;存在跳过
264
265
int h = fromTreeNode.Nodes.Count-1;
266
267
for (int i = h ; i>=0;i--)
268
269
{
270
271
TreeNode rootNode = new TreeNode();
272
273
rootNode = fromTreeNode.Nodes[i];
274
275
//根节点是否被选中,否则跳过。
276
277
if (rootNode.Checked == selected)
278
279
{
280
281
//本节点是否为叶子节点
282
283
bool isDeleted = false;
284
285
//子节点在 toTreeNode中的子节点集 中是否存在
286
287
if (!FindNodeFromChildNodes (rootNode,toTreeNode))
288
289
{
290
291
//移动节点,判断是否为子节点。是子节点则从fromTreeNode中移除,同时判断是否为唯一节点,是同时移除父节点,
292
293
//反之忽略。
294
295
TreeNode rootNodeClone = ((TreeNode)rootNode.Clone());
296
297
int k = rootNodeClone.Nodes.Count;
298
299
for(int j=0; j<k;j++)
300
301
{
302
303
rootNodeClone.Nodes.RemoveAt(0);
304
305
}
306
307
toTreeNode.Nodes.Add(rootNodeClone);
308
309
310
311
isDeleted = RemoveLeafageChildNode(ref rootNode);
312
313
}
314
315
316
317
//移动子节点的整个分支
318
319
if (!isDeleted)
320
321
{
322
323
TreeNode toRootNode = new TreeNode();
324
325
//定位toTreeNode中与rootNode相同的节点位置。
326
327
FindNodeFromChildNodes(rootNode,toTreeNode,ref toRootNode);
328
329
//移动fromTreeNode中rootNode的分支中所有选中节点到toTreeNode的toRootNode分支中
330
331
MoveNodes(ref rootNode,ref toRootNode);
332
333
}
334
335
}
336
337
}
338
339
}
340
341
/// <summary>
342
343
/// 【MoveNodes】将一棵树中所有被选中的节点,移动到另外一棵树上。前提根节点必须保留,且各节点Text值唯一。
344
345
/// </summary>
346
347
/// <param name="fromTreeNode"></param>
348
349
/// <param name="toTreeNode"></param>
350
351
public void MoveNodes(ref TreeView fromTreeView,ref TreeView toTreeView)
352
353
{
354
355
bool selected = true;
356
357
358
359
//遍历fromTreeView根节点,比较选中节点在toTreeView的根节点集中是否存在,不存在则移动节点;存在跳过
360
361
362
363
int h = fromTreeView.Nodes.Count-1;
364
365
for (int i = h ; i>=0;i--)
366
367
{
368
369
TreeNode rootNode = new TreeNode();
370
371
rootNode = fromTreeView.Nodes[i];
372
373
//根节点是否被选中,否则跳过。
374
375
if (rootNode.Checked == selected)
376
377
{
378
379
//本节点是否为叶子节点
380
381
bool isDeleted = false;
382
383
//根节点在 toTreeView中的根节点中是否存在
384
385
if (!FindNodeFromChildNodes (rootNode,toTreeView))
386
387
{
388
389
//移动节点,判断是否为子节点。是子节点则从fromTreeView中移除,同时判断是否为唯一节点,是同时移除父节点,
390
391
//反之忽略。
392
393
TreeNode rootNodeClone = ((TreeNode)rootNode.Clone());
394
395
int k = rootNodeClone.Nodes.Count;
396
397
for(int j=0; j<k;j++)
398
399
{
400
401
rootNodeClone.Nodes.RemoveAt(0);
402
403
}
404
405
406
407
toTreeView.Nodes.Add(rootNodeClone);
408
409
410
411
isDeleted = RemoveLeafageChildNode(ref rootNode);
412
413
}
414
415
//移动根节点的整个分支
416
417
if (!isDeleted)
418
419
{
420
421
TreeNode toRootNode = new TreeNode();
422
423
//定位toTreeView中与rootNode相同的节点位置。
424
425
FindNodeFromChildNodes(rootNode,toTreeView,ref toRootNode);
426
427
//移动fromTreeView中rootNode的分支中所有选中节点到toTreeView的toRootNode分支中
428
429
MoveNodes(ref rootNode,ref toRootNode);
430
431
}
432
433
}
434
435
}
436
437
}
438
439
440
441
#endregion
442

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

[THE END]
搜索一下相关内容 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合终身会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步