博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MVVM模式下实现拖拽
阅读量:4365 次
发布时间:2019-06-07

本文共 5866 字,大约阅读时间需要 19 分钟。

在文章开始之前先看一看效果图

我们可以拖拽一个"游戏"给ListBox,并且ListBox也能接受拖拽过来的数据, 但是我们不能拖拽一个"游戏类型"给它。

所以当拖拽开始发生的时候我们必须添加一些限制条件,以防止接受不正确的数据。

 

 

Item实体

CS

public class ItemModel : ViewModelBase    {        public string ItemName { get; set; }    }

 

组实体

CS

public class GroupModel : ViewModelBase    {        ///         /// 组名        ///         public string GroupName { get; set; }        private int groupCount;        ///         /// 组数量        ///         public int GroupCount        {            get { return groupCount; }            set { groupCount = value; base.RaisePropertyChanged("GroupCount"); }        }        ///         /// 子类集合        ///         public ObservableCollection
ItemModelList { get; set; } }

 

给"游戏"实体创建一个模板

XAML

 

给"游戏组"实体创建一个模板

XAML

 

但是当我准备给TreeView赋值的时候 , 我想起来TreeView的SelectedItem属性不是依赖属性 , 它不支持Binding操作

所以只有自己写一个控件继承TreeView了。为它扩展一个MySelectedItem属性出来。并且重写SelectedItemChange事件

把TreeView的SelectedItem交给扩展的依赖属性MySelectedItem .这样在界面上就可以Binding选中项了

不过由于TreeView各个节点的数据实体可能类型不相同,所以扩展的属性只能定义为object类型

 

创建自定义树

CS

public class MyTreeView : TreeView    {        public MyTreeView()        {        }        ///         /// 自定义TreeView选中项,支持数据Binding        ///         public object MySelectItem        {            get { return GetValue(MySelectItemProperty); }            set { SetValue(MySelectItemProperty, value); }        }        public static DependencyProperty MySelectItemProperty = DependencyProperty.Register("MySelectItem", typeof(object), typeof(MyTreeView));        ///         /// 当改变发生时,为自定义的SelectItem属性赋值        ///         ///         protected override void OnSelectedItemChanged(RoutedPropertyChangedEventArgs e)        {            if (this.SelectedItem != null)                this.MySelectItem = this.SelectedItem;            base.OnSelectedItemChanged(e);        }    }

XAML

 

CS

private TreeViewItem ti = new TreeViewItem();        private void TreeView_MouseMove(object sender, MouseEventArgs e)        {            if (e.LeftButton == MouseButtonState.Pressed)            {                if (myTree.SelectedItem == null)                    return;                DragDrop.DoDragDrop(ti, sender, DragDropEffects.Move);            }        }

DragDrop.DoDragDrop方法需要传入一个DependencyObject对象以设置其拖拽时的效果。

但由于TreeView做了数据绑定, 所以它的SelectItem取出来是一个数据实体。而不是一个DependencyObject对象了。

所以我用了一个比较SB的办法就是new一个TreeViewItem。然后设置拖拽移动的效果。

 

创建ListBox

ViewModel 

public class MainViewModel : ViewModelBase    {        public MainViewModel()        {            Init();        }        #region Properties        ///         /// 数据源        ///         public ObservableCollection
GroupSourceList { get; set; } ///
/// 数据源 /// public ObservableCollection
GameSourceList { get; set; } private object selectGame; ///
/// 当前选中项 /// public object SelectGame { get { return selectGame; } set { selectGame = value; base.RaisePropertyChanged("SelectGame"); } } #endregion #region Methods private void Init() { GameSourceList = new ObservableCollection
(); GroupSourceList = new ObservableCollection
(); GroupModel gp1 = new GroupModel(); #region 模拟数据 gp1.GroupName = "竞技游戏"; gp1.ItemModelList = new ObservableCollection
(); gp1.ItemModelList.Add(new ItemModel() { ItemName = "CS GO" }); gp1.ItemModelList.Add(new ItemModel() { ItemName = "星际争霸2" }); gp1.ItemModelList.Add(new ItemModel() { ItemName = "FIFA 14" }); gp1.GroupCount = gp1.ItemModelList.Count; GroupModel gp2 = new GroupModel(); gp2.GroupName = "网络游戏"; gp2.ItemModelList = new ObservableCollection
(); gp2.ItemModelList.Add(new ItemModel() { ItemName = "CS OnLine" }); gp2.ItemModelList.Add(new ItemModel() { ItemName = "街头篮球" }); gp2.ItemModelList.Add(new ItemModel() { ItemName = "完美世界" }); gp2.GroupCount = gp2.ItemModelList.Count; GroupModel gp3 = new GroupModel(); gp3.GroupName = "休闲游戏"; gp3.ItemModelList = new ObservableCollection
(); gp3.ItemModelList.Add(new ItemModel() { ItemName = "德州扑克" }); gp3.ItemModelList.Add(new ItemModel() { ItemName = "街头篮球" }); gp3.ItemModelList.Add(new ItemModel() { ItemName = "完美世界" }); GroupSourceList.Add(gp1); GroupSourceList.Add(gp2); GroupSourceList.Add(gp3); gp3.GroupCount = gp3.ItemModelList.Count; #endregion DragEnterCommand = new RelayCommand
(DragEnter); DropCommand = new RelayCommand
(Drop); } private void DragEnter(DragEventArgs args) { if (SelectGame.GetType() == typeof(ItemModel)) //如果拖拽的对象是"游戏"则接受之 { args.Effects = DragDropEffects.Move; System.Console.WriteLine("accept"); } else { args.Effects = DragDropEffects.None; //否则拒绝接受拖拽 System.Console.WriteLine("no accept"); } args.Handled = true; } private void Drop(DragEventArgs args) { GameSourceList.Add(SelectGame as ItemModel); //将接受到的"游戏"写入ListBox } #endregion #region Commands public ICommand DragEnterCommand { get; set; } public ICommand DropCommand { get; set; } #endregion }

到这里一个简单的拖拽就完成了。

QQ 3045568793 欢迎交流 

转载于:https://www.cnblogs.com/ShenNan/p/4275494.html

你可能感兴趣的文章
Maven编译unmappable character for encoding Cp1252问题
查看>>
xftp上传文件失败,执行程序发现磁盘满了:No space left on device
查看>>
duplicate symbols for architecture i386 问题?
查看>>
[BZOJ]1027 合金(JSOI2007)
查看>>
poj 1696 Space Ant (几何 : 叉积 应用 + dfs)
查看>>
MySQL:按前缀批量删除表格
查看>>
Route学习笔记之Area的Route注册
查看>>
构建之法--软件工程师自我测评表
查看>>
电子书搜索
查看>>
SQO2008配置管理工具服务显示远程过程调用失败
查看>>
【HDOJ】1009 FatMouse' Trade
查看>>
谷歌跨域
查看>>
使用葡萄城报表,轻松实现高度精准的报表套打
查看>>
Linux命令
查看>>
unicode ascii 互转 函数 C实现 MultiByteToWideChar/WideCharToMultiByte 详解
查看>>
大三第一学期实验报告
查看>>
mysql远程链接
查看>>
nginx location配置
查看>>
Easy Install详细参数
查看>>
选课系统
查看>>