MVVM模式下实现拖拽
在文章開(kāi)始之前先看一看效果圖
我們可以拖拽一個(gè)"游戲"給ListBox,并且ListBox也能接受拖拽過(guò)來(lái)的數(shù)據(jù), 但是我們不能拖拽一個(gè)"游戲類型"給它。
所以當(dāng)拖拽開(kāi)始發(fā)生的時(shí)候我們必須添加一些限制條件,以防止接受不正確的數(shù)據(jù)。
?
?
Item實(shí)體
CS
public class ItemModel : ViewModelBase{public string ItemName { get; set; }}?
組實(shí)體
CS
public class GroupModel : ViewModelBase{/// <summary>/// 組名/// </summary>public string GroupName { get; set; }private int groupCount;/// <summary>/// 組數(shù)量/// </summary>public int GroupCount{get { return groupCount; }set { groupCount = value; base.RaisePropertyChanged("GroupCount"); }}/// <summary>/// 子類集合/// </summary>public ObservableCollection<ItemModel> ItemModelList { get; set; }}?
給"游戲"實(shí)體創(chuàng)建一個(gè)模板
XAML
<HierarchicalDataTemplate x:Key="template_Item"><TextBlock Text="{Binding ItemName}"/> </HierarchicalDataTemplate>?
給"游戲組"實(shí)體創(chuàng)建一個(gè)模板
XAML
<HierarchicalDataTemplate x:Key="template_Group" ItemsSource="{Binding ItemModelList}" ItemTemplate="{StaticResource template_Item}"><StackPanel Orientation="Horizontal"><TextBlock Text="{Binding GroupName}"/><TextBlock Text="{Binding GroupCount}" Margin="5,0,0,0"/></StackPanel> </HierarchicalDataTemplate>?
但是當(dāng)我準(zhǔn)備給TreeView賦值的時(shí)候 , 我想起來(lái)TreeView的SelectedItem屬性不是依賴屬性 , 它不支持Binding操作
所以只有自己寫一個(gè)控件繼承TreeView了。為它擴(kuò)展一個(gè)MySelectedItem屬性出來(lái)。并且重寫SelectedItemChange事件
把TreeView的SelectedItem交給擴(kuò)展的依賴屬性MySelectedItem .這樣在界面上就可以Binding選中項(xiàng)了
不過(guò)由于TreeView各個(gè)節(jié)點(diǎn)的數(shù)據(jù)實(shí)體可能類型不相同,所以擴(kuò)展的屬性只能定義為object類型
?
創(chuàng)建自定義樹(shù)
CS
public class MyTreeView : TreeView{public MyTreeView(){}/// <summary>/// 自定義TreeView選中項(xiàng),支持?jǐn)?shù)據(jù)Binding/// </summary>public object MySelectItem{get { return GetValue(MySelectItemProperty); }set { SetValue(MySelectItemProperty, value); }}public static DependencyProperty MySelectItemProperty = DependencyProperty.Register("MySelectItem", typeof(object), typeof(MyTreeView));/// <summary>/// 當(dāng)改變發(fā)生時(shí),為自定義的SelectItem屬性賦值/// </summary>/// <param name="e"></param>protected override void OnSelectedItemChanged(RoutedPropertyChangedEventArgs<object> e){if (this.SelectedItem != null)this.MySelectItem = this.SelectedItem;base.OnSelectedItemChanged(e);}}XAML
<mc:MyTreeView x:Name="myTree" MouseMove="TreeView_MouseMove" TextBlock.FontSize="14" MySelectItem="{Binding SelectGame,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding GroupSourceList}" ItemTemplate="{StaticResource template_Group}"> </mc:MyTreeView>?
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方法需要傳入一個(gè)DependencyObject對(duì)象以設(shè)置其拖拽時(shí)的效果。
但由于TreeView做了數(shù)據(jù)綁定, 所以它的SelectItem取出來(lái)是一個(gè)數(shù)據(jù)實(shí)體。而不是一個(gè)DependencyObject對(duì)象了。
所以我用了一個(gè)比較SB的辦法就是new一個(gè)TreeViewItem。然后設(shè)置拖拽移動(dòng)的效果。
?
創(chuàng)建ListBox
<ListBox ItemsSource="{Binding GameSourceList}" AllowDrop="true"><ListBox.ItemTemplate><DataTemplate><TextBlock Text="{Binding ItemName}"/></DataTemplate></ListBox.ItemTemplate><i:Interaction.Triggers><i:EventTrigger EventName="DragEnter"><Command:EventToCommand Command="{Binding DragEnterCommand}" PassEventArgsToCommand="True"/></i:EventTrigger><i:EventTrigger EventName="DragOver"><Command:EventToCommand Command="{Binding DragEnterCommand}" PassEventArgsToCommand="True"/></i:EventTrigger><i:EventTrigger EventName="Drop"><Command:EventToCommand Command="{Binding DropCommand}" PassEventArgsToCommand="True"/></i:EventTrigger></i:Interaction.Triggers></ListBox>ViewModel?
public class MainViewModel : ViewModelBase{public MainViewModel(){Init();}#region Properties/// <summary>/// 數(shù)據(jù)源/// </summary>public ObservableCollection<GroupModel> GroupSourceList { get; set; }/// <summary>/// 數(shù)據(jù)源/// </summary>public ObservableCollection<ItemModel> GameSourceList { get; set; }private object selectGame;/// <summary>/// 當(dāng)前選中項(xiàng)/// </summary>public object SelectGame{get { return selectGame; }set{selectGame = value;base.RaisePropertyChanged("SelectGame");}}#endregion#region Methodsprivate void Init(){GameSourceList = new ObservableCollection<ItemModel>();GroupSourceList = new ObservableCollection<GroupModel>();GroupModel gp1 = new GroupModel();#region 模擬數(shù)據(jù)gp1.GroupName = "競(jìng)技游戲";gp1.ItemModelList = new ObservableCollection<ItemModel>();gp1.ItemModelList.Add(new ItemModel() { ItemName = "CS GO" });gp1.ItemModelList.Add(new ItemModel() { ItemName = "星際爭(zhēng)霸2" });gp1.ItemModelList.Add(new ItemModel() { ItemName = "FIFA 14" });gp1.GroupCount = gp1.ItemModelList.Count;GroupModel gp2 = new GroupModel();gp2.GroupName = "網(wǎng)絡(luò)游戲";gp2.ItemModelList = new ObservableCollection<ItemModel>();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<ItemModel>();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;#endregionDragEnterCommand = new RelayCommand<DragEventArgs>(DragEnter);DropCommand = new RelayCommand<DragEventArgs>(Drop);}private void DragEnter(DragEventArgs args){if (SelectGame.GetType() == typeof(ItemModel)) //如果拖拽的對(duì)象是"游戲"則接受之 {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 Commandspublic ICommand DragEnterCommand { get; set; }public ICommand DropCommand { get; set; }#endregion}到這里一個(gè)簡(jiǎn)單的拖拽就完成了。
QQ?3045568793 歡迎交流?
posted on 2019-03-15 13:18 NET未來(lái)之路 閱讀(...) 評(píng)論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/lonelyxmas/p/10536423.html
總結(jié)
以上是生活随笔為你收集整理的MVVM模式下实现拖拽的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 微信零钱通每日提现限额多少?转出到银行卡
- 下一篇: 跨行转账10万手续费多少?五家银行跨行转