• Silverlight4不同控件间拖拽实现附源码下载


    前天整理一份Silverlight 4中拖拽效果实现-附源码下载  在评论中一位园友提到实现不同控件间拖拽效果设想. 其实在项目中原本我遇到最初拖拽实现就是一个从TreeView中拖拽到一个ListBox中.中午正好看了Silverlight.net BBS和CrraySun.com上讨论.做了一个简单Demo实现.先看看效果:

      Get Microsoft Silverlight

    左边Listbox,右边Treeview.实现步骤如下

    A:页面布局:

    代码
     1   <Grid x:Name="LayoutRoot" Background="White"   HorizontalAlignment="Center" VerticalAlignment="Center">
     2         <Grid.RowDefinitions>
     3             <RowDefinition Height="40"></RowDefinition>
     4             <RowDefinition Height="350"></RowDefinition>
     5             <RowDefinition Height="10*" />
     6         </Grid.RowDefinitions>
     7         <Grid.ColumnDefinitions>
     8             <ColumnDefinition Width="300"></ColumnDefinition>
     9             <ColumnDefinition Width="300"></ColumnDefinition>
    10             <ColumnDefinition Width="200*" />
    11         </Grid.ColumnDefinitions>
    12         
    13         <TextBlock Text="Drag  Listbox to Treeview" Foreground="Red" FontFamily="Comic Sans MS" FontSize="16" Grid.ColumnSpan="2" Margin="85,12,162,0"></TextBlock>
    14         <!--左边一个listBox-->
    15         <toolKit:ListBoxDragDropTarget AllowDrop="True" Grid.Row="1" Grid.Column="0" >
    16             <ListBox x:Name="customerListBoxMain" Height="240" Width="215" SelectionMode="Extended"   DisplayMemberPath="CustomerName" BorderBrush="Black" BorderThickness="1">
    17                 <ListBox.ItemsPanel>
    18                     <ItemsPanelTemplate>
    19                         <StackPanel Orientation="Vertical"/>
    20                     </ItemsPanelTemplate>
    21                 </ListBox.ItemsPanel>
    22             </ListBox>
    23 
    24         </toolKit:ListBoxDragDropTarget>
    25         
    26         <!--右边一个Treeview-->
    27         <toolKit:TreeViewDragDropTarget AllowDrop="True" Grid.Row="1" Grid.Column="1" BorderThickness="1" BorderBrush="Red">
    28             <!--定义一个数据模板-->
    29             <toolKit:TreeViewDragDropTarget.Resources>
    30                 <my:HierarchicalDataTemplate x:Name="datetmp" ItemsSource="{Binding Customer}">
    31                     <TextBlock Text="{Binding CustomerName}"/>
    32                 </my:HierarchicalDataTemplate>
    33             </toolKit:TreeViewDragDropTarget.Resources>
    34             <sdk:TreeView x:Name="AcceptTreeview" Height="240" Width="215" ItemTemplate="{StaticResource datetmp}"> </sdk:TreeView>
    35             
    36         </toolKit:TreeViewDragDropTarget>
    37     </Grid>

    同上篇不同在TreeView中使用到了HierarchicalDataTemplate数据模板来定义Treeview数据显示. HierarchicalDataTemplate 数据模板默认是不添加的, 所以需要在页面添加引用如下:

    1     xmlns:my="clr-namespace:System.Windows;assembly=System.Windows.Controls"

    至于HierarchicalDataTemplate如何使用请参见MSDN.

    B:数据绑定-后台代码

    同样为了演示方便 直接写了一个类用来ListBox和Treeview中提供所需数据. 

    代码
     1  /// <summary>
     2     /// 为了达到演示目的 当前类提供list数据
     3     /// Author:chenkai Date:2010年5月28日10:21:36
     4     /// </summary>
     5     public class ProvideDate
     6     {
     7         public static List<Customer> GetAllCustomerList()
     8         {
     9             List<Customer> getcuslist = new List<Customer>();
    10             getcuslist.Add(new Customer { CustomerName="JackChen" });
    11             getcuslist.Add(new Customer { CustomerName = "Arrmy" });
    12             getcuslist.Add(new Customer { CustomerName = "SunSkyUnion" });
    13             getcuslist.Add(new Customer { CustomerName = "西藏拉萨" });
    14             getcuslist.Add(new Customer { CustomerName = "甘肃玉门关" });
    15 
    16             return getcuslist;
    17         }
    18 
    19 
    20         public static List<Customer> GetAllCustomerTreeList()
    21         {
    22             List<Customer> getcuslist = new List<Customer>();
    23             getcuslist.Add(new Customer { CustomerName = "markChen" });
    24             getcuslist.Add(new Customer { CustomerName = "KaiDun" });
    25             getcuslist.Add(new Customer { CustomerName = "GuideInformation" });
    26             getcuslist.Add(new Customer { CustomerName = "三门峡函谷关" });
    27             getcuslist.Add(new Customer { CustomerName = "嘉峪关" });
    28             getcuslist.Add(new Customer { CustomerName = "泰山" });
    29             getcuslist.Add(new Customer { CustomerName = "嵩山" });
    30 
    31             return getcuslist;
    32         }
    33     }
    34 
    35     public class Customer
    36     {
    37         public string CustomerName { getset; }
    38     }

     页面数据绑定: 

    代码
     1   //绑定ListBox数据
     2             List<Customer> getcuslist = TestSilverlightOutOfBrowerDemo.Date.ProvideDate.GetAllCustomerList();
     3             if (getcuslist != null)
     4             {
     5                 ObservableCollection<Customer> getlist = new ObservableCollection<Customer>();
     6                 foreach (Customer getcus in getcuslist)
     7                 {
     8                     getlist.Add(getcus);
     9                 }
    10                 this.customerListBoxMain.ItemsSource = getlist;
    11             }
    12 
    13             //绑定Treeview数据
    14             List<Customer> gettreeviewlist=TestSilverlightOutOfBrowerDemo.Date.ProvideDate.GetAllCustomerTreeList();
    15             ObservableCollection<Customer> getviewlist = new ObservableCollection<Customer>();
    16             foreach (Customer getcustree in gettreeviewlist)
    17              {
    18                 getviewlist.Add(getcustree);
    19              }
    20 
    21             this.AcceptTreeview.ItemsSource = getviewlist;
    22             

     因为使用ObservableCollection一个动态数据集合,需要在添加一个空间引用:

    1 using System.Collections.ObjectModel;

    ObservableCollection动态数据集合,这次数据通过绑定来实现.动态数据集合,在添加项、移除项或刷新整个列表时,此集合将提供通知 具体参见:MSDN 

    如上即简单实现了一个listbox向一个TreeView中拖拽实现,其实我当初在实现这问题,参考大量资料. 我想说一下个人对这个拖拽实现思路理解.首先我想说的是在整个拖拽过程事件执行过程,

    注意:虽然实现了Treeview在Listbox之间拖拽,但真正拖拽事件发生是在TreeViewDragDropTarget和ListBoxDragDropTarget控件中. 不要误认为是ListBox或Treeview本身.

    (1)先看看TreeViewDragDropTarget关于Drag事件.

    分别为Drop,DragOver, DragLeave,DragEnter. 这三个真正执行顺序如下: 

     

     执行场景:当把一个Listbox一个项拖拽到Treeview时 从DragEnter开始执行到DragOver. 其实上面实现完全是利用数据模板和DragDropTraget控件便利. 来整理一下在Sl3.0中实现一个拖拽需要具体步骤拆分:

    A:实现一个拖动图像,作为开始拖拽时的快照

    B:找到程序的root visual根视觉(如StackPanel) 

    C:将拖动图像添加到根视觉,并得到它的绝对坐标[动态坐标数据-难点]

    D:在运动时保持鼠标与拖动图像同步,随时给出是否在落下目标(drop target)上的视觉反馈 [需要动画效果]

    E:处理用户释放鼠标时刻,当经过落下目标时可以适当地动作,甚至可以显示一段不错的动画

    如此就在Silverlight 3.0拖拽效果.当然在4.0加以封装来实现.如何来获得拖拽实时数据 和SL3.0有点不同.

    (2)获得拖拽实时数据

    其实拖拽时listBox中数据都放在ItemContainer数据容器中,当拖拽一项时既是反映到ItemContainer中就是Remove删除一项,反而言之 接受一方Treeview中数据容器这是Add添加一个新项. 这就给我们提供一个监听拖拽数据机会.我们可以在listbox中ItemContainerGenerator.ItemsChanged定义一个监听事件. 来获取当前拖拽项.

    1             //附属一个监听事件 ItemsChanged 事件由 IItemContainerGenerator 引发,以通知布局项集合已更改
    2             this.AcceptTreeview.ItemContainerGenerator.ItemsChanged += new System.Windows.Controls.Primitives.ItemsChangedEventHandler(ItemContainerGenerator_ItemsChanged);

    事件实现:

     1     void ItemContainerGenerator_ItemsChanged(object sender, System.Windows.Controls.Primitives.ItemsChangedEventArgs e)
     2         {
     3             if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
     4             {
     5                 //e.Position获取集合中更改发生的位置
     7                 int index = (e.Position.Index + e.Position.Offset);
     8                 MessageBox.Show("total:" + this.AcceptTreeview.Items.Count.ToString() + "Index:" + index.ToString());
     9                 object obj = this.AcceptTreeview.Items[index];
    10 
    11                 if (obj != null)
    12                 {
    13                     TreeViewItem getitem = obj as TreeViewItem;
    14                     MessageBox.Show(getitem.Header.ToString());
    15 
    16                     ListBoxItem getboxitem = obj as ListBoxItem;
    17                     MessageBox.Show(getboxitem.Content.ToString());
    18                 }
    19             }
    20         }

    通过附属的ItemsChangedEventArgs 附带事件信息. 来判断当前对数据容器ItemContainer操作类型,System.Collections.Specialized.NotifyCollectionChangedAction是一个操作枚举. 包含None Add REmove. 判断拖拽状态后即可通过E.Position来获取数据项发生的位置. 集合通过装换获得具体拖拽项.当然也可定义其他操作. 

  • 相关阅读:
    深入理解DOM节点类型第三篇——注释节点和文档类型节点
    深入理解DOM节点类型第二篇——文本节点Text
    深入学习jQuery选择器系列第八篇——过滤选择器之伪子元素选择器
    深入学习jQuery选择器系列第七篇——表单选择器
    深入学习jQuery选择器系列第六篇——过滤选择器之状态选择器
    深入学习jQuery选择器系列第五篇——过滤选择器之内容选择器
    深入学习jQuery选择器系列第四篇——过滤选择器之属性选择器
    深入学习jQuery选择器系列第三篇——过滤选择器之索引选择器
    深入学习jQuery选择器系列第二篇——过滤选择器之子元素选择器
    RAID一个硬盘FAIL。
  • 原文地址:https://www.cnblogs.com/chenkai/p/1746559.html
Copyright © 2020-2023  润新知