打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
日志
WPF实现TreeView项的拖动及右键菜单
项目需求背景,用一个TreeView控件实现一个部门的层级显示,当需要把一个部门移动到另一个部门时,我们只需要把部门按层级展开,把源部门拖动到目标部门,然后根据需要的功能实现相应的鼠标右键功能。
1、创建一个部门类Department
public class Department
{
public int ID { get; set; }
public int ParentID { get; set; }
public string Name { get; set; }
public List<Department> Departments;
public Department(int id, int parentid, string name)
{
ID = id;
ParentID = parentid;
Name = name;
Departments = new List<Department>();
}
}
2、一个公共方法类 CommanClass
public class CommanClass
{
public List<Department> DepartmentCollection;
public CommanClass()
{
DepartmentCollection = CreateOrignDepartments();
}
public List<Department> CreateOrignDepartments()
{
List<Department> departs = new List<Department>();
departs.Add(new Department(1, 0, "大学"));
departs.Add(new Department(2, 1, "理学院"));
departs.Add(new Department(3, 1, "工学院"));
departs.Add(new Department(4, 1, "文学院"));
departs.Add(new Department(5, 2, "数学系"));
departs.Add(new Department(6, 2, "物理系"));
departs.Add(new Department(7, 3, "机械工程系"));
departs.Add(new Department(8, 3, "土木工程系"));
departs.Add(new Department(9, 3, "电子自动化系"));
departs.Add(new Department(10, 4, "外语系"));
departs.Add(new Department(11, 4, "古文学系"));
departs.Add(new Department(12, 4, "历史系"));
departs.Add(new Department(13, 4, "中文系"));
return departs;
}
// 创建层级结构的根节点
public void CreateTreeView(TreeView treeView)
{
foreach (var d in DepartmentCollection)
{
if (d.ParentID == 0)
{
TreeViewItem rootItem = new TreeViewItem();
rootItem.Header = d.Name;
rootItem.Tag = d;
treeView.Items.Add(rootItem);
CreateTreeViewItem(rootItem,d);
}
}
}
// 创建层级结构的子节点
private void CreateTreeViewItem(TreeViewItem childItem,Department parent)
{
foreach (var d in DepartmentCollection)
{
if (d.ParentID == parent.ID)
{
TreeViewItem child = new TreeViewItem();
child.Header = d.Name;
child.Tag = d;
childItem.Items.Add(child);
CreateTreeViewItem(child, d);
}
}
}
}
3、前台页面
<Grid>
<TreeView Name="treeView" Width="200" AllowDrop="True">
<TreeView.ContextMenu>
<ContextMenu Name="tvMenu" Width="120" HorizontalAlignment="Left" VerticalAlignment="Top">
<MenuItem Header="添加" Name="miAdd"/>
<MenuItem Header="删除" Name="miDel"/>
</ContextMenu>
</TreeView.ContextMenu>
</TreeView>
</Grid>
4、后台实现拖拽方法
首先需要把部门层级加载出来,只需调用CommanClass类的CreateTreeView方法即可
实现拖拽需要用到DragOver、Drop和MouseMove事件
treeView.MouseMove += new MouseEventHandler(treeView_MouseMove);
treeView.DragOver += new DragEventHandler(treeView_DragOver);
treeView.Drop += new DragEventHandler(treeView_Drop);
三个公共变量
private Point _LastMouseDown;//鼠标按下的位置
private TreeViewItem draggedItem, _target; //鼠标拖动项和存放的目标项
//实现treeView.DragOver 事件
void treeView_DragOver(object sender, DragEventArgs e)
{
try
{
Point currentPosition = e.GetPosition(treeView);
if ((Math.Abs(currentPosition.X - _LastMouseDown.X) > 10.0) || (Math.Abs(currentPosition.Y - _LastMouseDown.Y) > 10.0))
{
TreeViewItem item = GetNearestContainer(e.OriginalSource as UIElement);
e.Effects = CheckDropTarget(draggedItem, item) ? DragDropEffects.Move : DragDropEffects.None;
}
e.Handled = true;
}
catch { }
}
//获取TreeViewItem
private TreeViewItem GetNearestContainer(UIElement element)
{
TreeViewItem container = element as TreeViewItem;
while ((container == null) && (element != null))
{
element = VisualTreeHelper.GetParent(element) as UIElement;
container = element as TreeViewItem;
}
return container;
}
// 判断源项和目标项是否是自己本身
private bool CheckDropTarget(TreeViewItem sourceItem, TreeViewItem targetItem)
{
bool isEqual = false;
if (sourceItem != null && targetItem != null)
{
if (!sourceItem.Header.ToString().Equals(targetItem.Header.ToString()))
{
isEqual = true;
}
}
return isEqual;
}
实现treeView.Drop 事件
void treeView_Drop(object sender, DragEventArgs e)
{
try
{
e.Effects = DragDropEffects.None;
e.Handled = true;
TreeViewItem targetItem = GetNearestContainer(e.OriginalSource as UIElement);
if (targetItem != null && draggedItem != null)
{
_target = targetItem;
e.Effects = DragDropEffects.Move;
}
}
catch { }
}
//实现 treeView.MouseMove 事件
void treeView_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point currentPoint = e.GetPosition(treeView);
if ((Math.Abs(currentPoint.X - _LastMouseDown.X) > 10.0) || (Math.Abs(currentPoint.Y - _LastMouseDown.Y) > 10.0))
{
draggedItem = (TreeViewItem)treeView.SelectedItem;
if (draggedItem != null)
{
DragDropEffects finalDropEffect = DragDrop.DoDragDrop(treeView, treeView.SelectedValue, DragDropEffects.Move);
if ((finalDropEffect == DragDropEffects.Move) && _target != null)
{
if (!draggedItem.Header.ToString().Equals(_target.Header.ToString()))
{
CopyItem(draggedItem, _target);
_target = null;
draggedItem = null;
}
}
}
}
}
}
catch
{ }
}
private void CopyItem(TreeViewItem sourceItem, TreeViewItem targetItem)
{
if (MessageBox.Show("是否将<" + sourceItem.Header.ToString() + ">移动到<" + targetItem.Header.ToString() + ">之下?", "询问",MessageBoxButton.YesNo , MessageBoxImage.Question) == MessageBoxResult.Yes)
{
AddChildFromDropItem(sourceItem, targetItem);
TreeViewItem parentItem = FindVisualParent<TreeViewItem>(sourceItem);
//在源项的父项中移除源项
if (parentItem == null)
treeView.Items.Remove(sourceItem);
else
parentItem.Items.Remove(sourceItem);
}
}
//把源项及其子项移动到目标项
private void AddChildFromDropItem(TreeViewItem sourceItem, TreeViewItem targetItem)
{
if (sourceItem != null && targetItem != null)
{
TreeViewItem addItem = new TreeViewItem();
addItem.Header = sourceItem.Header;
addItem.Tag = sourceItem.Tag;
Department source = addItem.Tag as Department;
Department target = targetItem.Tag as Department;
if (source != null && target != null)
{
source.ParentID = target.ID;
}
targetItem.Items.Add(addItem);
foreach (TreeViewItem item in sourceItem.Items)
{
AddChildFromDropItem(item, addItem);
}
}
}
//找到需要拖拽项的父项
private T FindVisualParent<T>(UIElement child) where T : UIElement
{
if (child == null)
return null;
UIElement parent = VisualTreeHelper.GetParent(child) as UIElement;
while (parent != null)
{
T found = parent as T;
if (found != null)
return found;
else
parent = VisualTreeHelper.GetParent(parent) as UIElement;
}
return null;
}
最后实现右键菜单只需要在Loaded事件中加载MenuItem的Click事件就行
例如删除右键
miDel.Click += new RoutedEventHandler(miDel_Click);
void miDel_Click(object sender, RoutedEventArgs e)
{
//throw new NotImplementedException();
}
最后实现效果
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
有关Silverlight TreeView组件的研究[2]_银光中国 Silverlig...
WPF TreeView Win8 样式
【silverlight】Silverlight TreeViw默认展开节点
访问扩展点_DM
使用Silverlight Toolkit TreeView树形控件
Advanced Custom TreeView Layout in WPF
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服