• MVVM模式下实现拖拽


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

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

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

    Item实体

    CS

    1
    2
    3
    4
    public class ItemModel : ViewModelBase
    {
        public string ItemName { get; set; }
    }

    组实体

    CS

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

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

    XAML

    <HierarchicalDataTemplate x:Key="template_Item">
           <TextBlock Text="{Binding ItemName}"/>
    </HierarchicalDataTemplate>

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

    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>
    复制代码

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

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

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

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

    创建自定义树

    CS

    复制代码
    public class MyTreeView : TreeView
        {
            public MyTreeView()
            {
    
            }
    
            /// <summary>
            /// 自定义TreeView选中项,支持数据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>
            /// 当改变发生时,为自定义的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方法需要传入一个DependencyObject对象以设置其拖拽时的效果。

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

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

    创建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>
            /// 数据源
            /// </summary>
            public ObservableCollection<GroupModel> GroupSourceList { get; set; }
    
            /// <summary>
            /// 数据源
            /// </summary>
            public ObservableCollection<ItemModel> GameSourceList { get; set; }
    
    
            private object selectGame;
            /// <summary>
            /// 当前选中项
            /// </summary>
            public object SelectGame
            {
                get { return selectGame; }
                set
                {
                    selectGame = value;
                    base.RaisePropertyChanged("SelectGame");
                }
            }
            #endregion
    
            #region Methods
            private void Init()
            {
                GameSourceList = new ObservableCollection<ItemModel>();
                GroupSourceList = new ObservableCollection<GroupModel>();
                GroupModel gp1 = new GroupModel();
                #region 模拟数据
                gp1.GroupName = "竞技游戏";
                gp1.ItemModelList = new ObservableCollection<ItemModel>();
                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<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;
                #endregion
                DragEnterCommand = new RelayCommand<DragEventArgs>(DragEnter);
                DropCommand = new RelayCommand<DragEventArgs>(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
        }
    复制代码

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

    原地址:http://www.cnblogs.com/ShenNan/p/4275494.html

  • 相关阅读:
    Freemarker-2.3.22 Demo
    Freemarker-2.3.22 Demo
    Freemarker-2.3.22 Demo
    Freemarker-2.3.22 Demo
    Oracle PLSQL Demo
    Oracle PLSQL Demo
    Oracle PLSQL Demo
    Oracle PLSQL Demo
    Oracle PLSQL Demo
    Oracle PLSQL Demo
  • 原文地址:https://www.cnblogs.com/lsgsanxiao/p/4705260.html
Copyright © 2020-2023  润新知