好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

重写SurfaceListBox 完善DragDrop

重写SurfaceListBox 完善DragDrop

刚才不小心睡着了一会,一醒,看到现在都是五点多了,头脑有点不清醒,就不继续coding了,整理一下今天修改的东西,重写SurfaceListBox的DragDrop

本次重写指在完善一下功能(如图所示):

  1,从下面的数据列表拖动数据到上面的列表中

  2,拖动下面的数据时,只有图片能拖进去,其他类型的会直接显示出来

  3,在拖进图片时,如果有别的元素遮挡,那么也是显示出图片而不是拖入(问题出现,标记为A)

  4,在界面显示的时候,除了图片以外,别的类型不能拖入,并保持拖入时其他元素的状态(问题标记为B)

下面介绍一下会出现的问题:

  A,在wpf中,Microsoft.Surface.Presentation.SurfaceDragDrop的事件,即使在你注册监听事件的元素上面还有元素遮挡,这个事件依旧会触发,触发的后果就是,你没有把元素添加进去,但是,鼠标数据依旧已经在此过程被处理,原因同B

  B,在鼠标数据触发到事件以后,哪怕是(SurfaceDragDrop.PreviewDragEnterEvent),在这个事件之中,鼠标数据的 DragDropEffects会被触发,表现在,这个事件之后数据没了,不相信的话,可以测试,使用代码中的 (thisParent.ItemContainerGenerator.ContainerFromItem(data) as ScatterViewItem),在【SurfaceDragDrop.AddDropHandler(this, OnCursorDrop);】中thisParent已经不包含鼠标数据了

  由于B的原因,我本想多实现一项功能(如果界面已经显示包含下面数据的元素,那么如果再拖拽到上面的列表时把元素移位到拖拽释放的位置,而不是直接屏蔽消息),可是我试了几种想法,都未曾能成功,也就暂时搁置这个功能了

View Code

 *  *
* FileName:  SPListBox.cs
* Version:   1.0
* Date:      2012.05.22
* Author:    Ji
*========================================
* @namespace    Colavia.SPCommonControl
* @class        SPListBox
* @extends      SurfaceListBox
*
* 
*========================================
* Copyright (c) 2012 Colavia
  */ 
 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   Microsoft.Surface.Presentation.Controls;
  using   System.Windows.Media;
  using   System.Windows;
  using   Microsoft.Surface.Presentation;
  using   System.Windows.Input;
  using   System.Diagnostics;
  using   Microsoft.Surface.Presentation.Input;
  using   System.Windows.Controls;
  using   System.Xml;
  using   Colavia.SPBaseDataInterface;
  using   Colavia.SPObjectInterface;
  using   Colavia.SPCommonControl;

  namespace   Colavia.SPToolsControl
{
      public   class   SPListBox : SurfaceListBox
    {
          public   SPListBox()
        {
            Background  =  Brushes.Transparent;
            AllowDrop  =  true  ;

              this .Loaded += (s, e) => 
            {
                SurfaceDragDrop.AddDropHandler(  this  , OnCursorDrop);
            };
              this .Unloaded += (s, e) => 
            {
                SurfaceDragDrop.RemoveDropHandler(  this  , OnCursorDrop);
            };

              this .AddHandler(SPListBox.TouchDownEvent,  new  EventHandler<TouchEventArgs>(SPListBox_PreviewTouchDown),  true  );
              this .AddHandler(SPListBox.TouchUpEvent,  new  EventHandler<TouchEventArgs>(SPListBox_PreviewTouchUp),  true  );
              this .AddHandler(SPListBox.TouchMoveEvent,  new  EventHandler<TouchEventArgs>(SPListBox_PreviewTouchMove),  true  );

              this .AddHandler(SPListBox.MouseLeftButtonDownEvent,  new  MouseButtonEventHandler(OnMouseLeftButtonDown),  true  );
              this .AddHandler(SPListBox.MouseLeftButtonUpEvent,  new  MouseButtonEventHandler(OnMouseLeftButtonUp),  true  );
              this .AddHandler(SPListBox.MouseMoveEvent,  new  MouseEventHandler(OnMouseMove),  true  );

              this .AddHandler(Microsoft.Surface.Presentation.SurfaceDragDrop.DragCompletedEvent,  new  System.EventHandler<Microsoft.Surface.Presentation.SurfaceDragCompletedEventArgs>( this  .OnListDragCompleted));
              this .AddHandler(Microsoft.Surface.Presentation.SurfaceDragDrop.DragCanceledEvent,  new  System.EventHandler<Microsoft.Surface.Presentation.SurfaceDragDropEventArgs>( this  .OnListDragCanceled));

              this .AddHandler(Microsoft.Surface.Presentation.SurfaceDragDrop.PreviewDragEnterEvent,  new  System.EventHandler<Microsoft.Surface.Presentation.SurfaceDragDropEventArgs>( this  .dragEnterEvent));

        }

        List < string > ImageEndWith =  new  List< string >() {  "  .jpg  " ,  "  .jpeg  " ,  "  .ico  " ,  "  .bmp  " ,  "  .icon  " ,  "  .gif  " ,  "  .png  "   };

          private   void  dragEnterEvent( object   sender, SurfaceDragDropEventArgs e)
        {
              var  thisParent = Find<ScatterView>((DependencyObject) this  );

            List < int > scatteritem =  new  List< int > ();
              int  slider =  new   int  ();
              foreach  ( var  scatterViewItem  in   thisParent.Items)
            {
                  var  sviItem = thisParent.ItemContainerGenerator.ContainerFromItem(scatterViewItem)  as   ScatterViewItem;
                  var  hTest =  VisualTreeHelper.HitTest(sviItem, Mouse.GetPosition(sviItem));
                  if  (hTest !=  null  )
                {
                      var  dataContext = (hTest.VisualHit  as   FrameworkElement).DataContext;

                      if  (dataContext !=  null  && e.Cursor.Data !=  null  && e.Cursor.Data !=  dataContext)
                    {
                          if  (dataContext  is   SPSlideEditor)
                        {
                            slider  =  sviItem.ZIndex;
                        }
                          else  
                        {
                            scatteritem.Add(sviItem.ZIndex);
                        }
                    }
                }
            }
              var  abri = scatteritem.FirstOrDefault(i => i >  slider);

            SurfaceDragCursor droppingCursor  =  e.Cursor;
              if  (droppingCursor.Data  is  SPObjectData || droppingCursor.Data  is   SPObjectBase)
            {
                  if  ( this .Items.Count <  MaxCount)
                {
                      var  objPlugin = (droppingCursor.Data  as  SPObjectData) !=  null  ? (droppingCursor.Data  as  SPObjectData).Object : droppingCursor.Data  as   SPObjectBase;

                      if  (objPlugin !=  null  )
                    {
                          if  (objPlugin.ClipUri !=  null  )
                        {
                              //  如果当前场景中已经存在,即已经是ScatterViewItem项 
                             if  (thisParent.Items.Contains(droppingCursor.Data  as   SPObjectData))
                            {
                                  //   var o = (thisParent.ItemContainerGenerator.ContainerFromItem(droppingCursor.Data as SPObjectData) as ScatterViewItem); 
                                 var  endJudge = ImageEndWith.FirstOrDefault(i =>  objPlugin.ClipUri.EndsWith(i));
                                  if  (endJudge ==  null  )
                                {
                                    e.Handled  =  true  ;
                                    e.Effects  =  DragDropEffects.None;
                                      return  ;
                                }
                            }
                        }
                          //  选项是从下面的轨道拖出
                          //  移交给OnCursorDrop处理元素添加的位置 
                         return  ;
                    }
                }
                  else  
                {
                      string  str =  string .Format( "  已经达到最大添加{0}数目,请删除后添加  "  , MaxCount);
                    SPSplashControl.Show(str);
                }
            }

            e.Handled  =  true  ;
            e.Effects  =  DragDropEffects.None;
        }

          #region  this.Event

         private   const   int  DragThreshold =  15  ;
          private  List<InputDevice> ignoredDeviceList =  new  List<InputDevice> ();

          private   void  OnListDragCanceled( object   sender, SurfaceDragDropEventArgs e)
        {
              var  draggingData =  e.Cursor.Data;
              if  (draggingData !=  null  &&  Items.Contains(draggingData))
            {
                ResetListBoxItem(draggingData);
            }
        }

          private   void  OnListDragCompleted( object   sender, SurfaceDragCompletedEventArgs e)
        {
              object  draggingData =  e.Cursor.Data;
              if  (draggingData !=  null  &&  Items.Contains(draggingData))
            {
                ResetListBoxItem(draggingData);
            }
        }

          //  <summary>
          //  接受事件--自身处理
          //  </summary>
          //  <param name="itemData"></param> 
         private   void  ResetListBoxItem( object   itemData)
        {

              if  (GetDragDelete( this ) &&  self)
            {
                  try  
                {
                    Items.Remove(itemData);
                }
                  catch   { }
            }
              else  
            {
                SurfaceListBoxItem sourceListBoxItem  =  null  ;
                  foreach  ( object  item  in   this  .Items)
                {
                      if  (item ==  itemData)
                    {
                        sourceListBoxItem  =  this .ItemContainerGenerator.ContainerFromItem(item)  as   SurfaceListBoxItem;
                    }
                }
                  if  (sourceListBoxItem !=  null  )
                {
                    sourceListBoxItem.Opacity  =  1  ;
                }
            }
              if  (! self)
            {
                self  =  true  ;
            }
        }

          private   void  OnMouseLeftButtonDown( object   sender, MouseButtonEventArgs e)
        {
            ignoredDeviceList.Remove(e.Device);
            InputDeviceHelper.ClearDeviceState(e.Device);
            InputDeviceHelper.InitializeDeviceState(e.Device);
        }

          private   void  OnMouseLeftButtonUp( object   sender, MouseButtonEventArgs e)
        {
            ignoredDeviceList.Remove(e.MouseDevice);
            InputDeviceHelper.ClearDeviceState(e.Device);
        }

          private   void  OnMouseMove( object   sender, MouseEventArgs e)
        {
            AllowDrop  =  true  ;
              if  (InputDeviceHelper.GetDragSource(e.Device) !=  null  )
            {
                StartDragDrop(  this  , e);
            }
        }

          private   void  SPListBox_PreviewTouchDown( object   sender, TouchEventArgs e)
        {
            ignoredDeviceList.Remove(e.Device);
            InputDeviceHelper.ClearDeviceState(e.Device);
            InputDeviceHelper.InitializeDeviceState(e.Device);
        }

          private   void  SPListBox_PreviewTouchUp( object   sender, TouchEventArgs e)
        {
            ignoredDeviceList.Remove(e.Device);
            InputDeviceHelper.ClearDeviceState(e.Device);
        }

          private   void  SPListBox_PreviewTouchMove( object   sender, TouchEventArgs e)
        {
            AllowDrop  =  true  ;
              if  (InputDeviceHelper.GetDragSource(e.Device) !=  null  )
            {
                StartDragDrop(  this  , e);
            }
        }

          //  <summary>
          //  拖动事件
          //  </summary>
          //  <param name="sender"></param>
          //  <param name="args"></param> 
         private   void   StartDragDrop(ListBox sourceListBox, InputEventArgs e)
        {
              if   (ignoredDeviceList.Contains(e.Device))
            {
                  return  ;
            }
            InputDeviceHelper.InitializeDeviceState(e.Device);
            Vector draggedDelta  =  InputDeviceHelper.DraggedDelta(e.Device, (UIElement)sourceListBox);
              if  (Math.Abs(draggedDelta.Y) >  DragThreshold)
            {
                ignoredDeviceList.Add(e.Device);
                  return  ;
            }
              if  (Math.Abs(draggedDelta.X) <  DragThreshold)
            {
                  return  ;
            }
            ignoredDeviceList.Add(e.Device);
            DependencyObject downSource  =  InputDeviceHelper.GetDragSource(e.Device);

            SurfaceListBoxItem draggedListBoxItem  = GetVisualAncestor<SurfaceListBoxItem> (downSource);
              if  (draggedListBoxItem ==  null  )
            {
                  return  ;
            }
              object  data =  draggedListBoxItem.Content;

            Image image  =  new   Image();
            image.Source  = (data  as  SliderData).Plugin.Icon  as   ImageSource;

            IEnumerable <InputDevice> devices =  null  ;
            TouchEventArgs touchEventArgs  = e  as   TouchEventArgs;
              if  (touchEventArgs !=  null  )
            {
                devices  =  MergeInputDevices(draggedListBoxItem.TouchesCapturedWithin, e.Device);
            }
              else  
            {
                devices  =  new  List<InputDevice>( new   InputDevice[] { e.Device });
            }

            IList <SliderData> itemsSource = ItemsSource  as  IList<SliderData> ;


              object  dd =  new   object  ();
              if  ((data  as  SliderData).ObjectData !=  null  )
            {
                dd  = (data  as   SliderData).ObjectData;
            }
              else  
            {
                dd  = (data  as   SliderData).Plugin;
            }

            SurfaceDragCursor cursor  = SurfaceDragDrop.BeginDragDrop( this  , draggedListBoxItem, image, dd, devices, DragDropEffects.Move);

            itemsSource.Remove(data   as   SliderData);

              if  (cursor ==  null  )
            {
                  return  ;
            }

            InputDeviceHelper.ClearDeviceState(e.Device);
            ignoredDeviceList.Remove(e.Device);

            draggedListBoxItem.Opacity  =  0.5  ;
        }

          private   static  T GetVisualAncestor<T>(DependencyObject descendent)  where  T :  class  
        {
            T ancestor  =  null  ;
            DependencyObject scan  =  descendent;
            ancestor  =  null  ;

              while  (scan !=  null  && ((ancestor = scan  as  T) ==  null  ))
            {
                scan  =  VisualTreeHelper.GetParent(scan);
            }

              return   ancestor;
        }

          private   static  IEnumerable<InputDevice> MergeInputDevices(IEnumerable<TouchDevice>  existingInputDevices, InputDevice extraInputDevice)
        {
              var  result =  new  List<InputDevice>  { extraInputDevice };

              foreach  (InputDevice inputDevice  in   existingInputDevices)
            {
                  if  (inputDevice !=  extraInputDevice)
                {
                    result.Add(inputDevice);
                }
            }
              return   result;
        }

          private   bool  self =  true  ;

          //  <summary>
          //  接受事件
          //  </summary>
          //  <param name="sender"></param>
          //  <param name="args"></param> 
         private   void  OnCursorDrop( object   sender, SurfaceDragDropEventArgs args)
        {
              var  thisParent = Find<ScatterView>((DependencyObject) this  );

            List < int > scatteritem =  new  List< int > ();
              int  slider =  new   int  ();
              foreach  ( var  scatterViewItem  in   thisParent.Items)
            {
                  var  sviItem = thisParent.ItemContainerGenerator.ContainerFromItem(scatterViewItem)  as   ScatterViewItem;
                  var  hTest =  VisualTreeHelper.HitTest(sviItem, Mouse.GetPosition(sviItem));
                  if  (hTest !=  null  )
                {
                      var  dataContext = (hTest.VisualHit  as   FrameworkElement).DataContext;

                      if  (dataContext !=  null  && args.Cursor.Data !=  null  && args.Cursor.Data !=  dataContext)
                    {
                          if  (dataContext  is   SPSlideEditor)
                        {
                            slider  =  sviItem.ZIndex;
                        }
                          else  
                        {
                            scatteritem.Add(sviItem.ZIndex);
                        }
                    }
                }
            }
              var  abri = scatteritem.FirstOrDefault(i => i >  slider);

            SurfaceDragCursor droppingCursor  =  args.Cursor;
            SPObjectBase objPlugin  =  null  ;
            objPlugin  = (droppingCursor.Data  as  SPObjectData) !=  null  ? (droppingCursor.Data  as  SPObjectData).Object : droppingCursor.Data  as   SPObjectBase;

              //  对于从下面拖拽的元素类型判断 
             if  (objPlugin !=  null   )
            {
                  if  (objPlugin.ClipUri !=  null  )
                {
                      var  endJudge = ImageEndWith.FirstOrDefault(i =>  objPlugin.ClipUri.EndsWith(i));
                      if  (endJudge ==  null  )
                    {
                        abri  =  1  ;
                    }
                }
                  else  
                {
                    abri  =  2  ;
                }
            }

              if  (abri ==  0  )
            {
                  #region  Add into items 

                IList <SliderData> itemsSource = ItemsSource  as  IList<SliderData> ;
                SliderData dataDrop  =  new   SliderData();

                  if  ((droppingCursor.Data  is  SPObjectData) || droppingCursor.Data  is   SPObjectBase)
                {

                      if  (objPlugin ==  null  )
                    {
                          return  ;
                    }

                      try  
                    {
                        dataDrop  = itemsSource.FirstOrDefault(i => i.Plugin ==  objPlugin);
                        itemsSource.Remove(dataDrop);
                    }
                      catch   { }

                      if  (dataDrop ==  null  )
                    {
                        dataDrop  =  new   SliderData();
                    }

                    dataDrop.Plugin  =  objPlugin;
                    dataDrop.ObjectData  = (droppingCursor.Data  as   SPObjectData);
                      if  (droppingCursor.CurrentTarget ==  this  )
                    {
                          //  if (droppingCursor.DragSource != this) 
                         {
                              try  
                            {
                                  var  exsit = itemsSource.FirstOrDefault(i => i.Plugin ==  dataDrop.Plugin);
                                  try  
                                {
                                      if  (exsit !=  null  )
                                    {
                                        itemsSource.Remove(exsit);
                                    }
                                }
                                  catch   { }

                                {
                                      var  h = VisualTreeHelper.HitTest( this , Mouse.GetPosition( this  ));
                                      if  (h !=  null  )
                                    {
                                          var  obj =  h.VisualHit;
                                        SurfaceListBoxItem lb  =  new   SurfaceListBoxItem();
                                        itemsSource.Remove(exsit);
                                          if  (obj !=  null  )
                                        {
                                            lb  = Find<SurfaceListBoxItem> ((DependencyObject)obj);

                                              if  (lb !=  null  )
                                            {
                                                  var  mouseIndex = itemsSource.IndexOf( this .ItemContainerGenerator.ItemFromContainer((DependencyObject)lb)  as   SliderData);
                                                itemsSource.Insert(mouseIndex, dataDrop);
                                            }
                                              else  
                                            {
                                                itemsSource.Add(dataDrop);
                                            }
                                              this  .ScrollIntoView(dataDrop);
                                        }
                                    }
                                      else  
                                    {
                                          if  (dataDrop !=  null  )
                                        {
                                            itemsSource.Add(dataDrop);
                                              this  .ScrollIntoView(dataDrop);
                                              return  ;
                                        }
                                    }
                                }
                            }
                              catch   { }
                        }
                    }
                }
                  else   if  ((droppingCursor.Data  is   SliderData))
                {
                    dataDrop  = droppingCursor.Data  as   SliderData;
                    SurfaceListBoxItem sourceListBoxItem  =  null  ;
                      foreach  (SliderData item  in   itemsSource)
                    {
                          if  (item ==  dataDrop)
                        {
                            sourceListBoxItem  =  this .ItemContainerGenerator.ContainerFromItem(item)  as   SurfaceListBoxItem;
                        }
                    }
                      var  h = VisualTreeHelper.HitTest( this , Mouse.GetPosition( this  ));
                      if  (h !=  null  )
                    {
                          var  obj =  h.VisualHit;
                        SurfaceListBoxItem lb  =  new   SurfaceListBoxItem();
                          if  (obj !=  null  )
                        {
                              try  
                            {
                                itemsSource.Remove(dataDrop);
                                lb  = Find<SurfaceListBoxItem> ((DependencyObject)obj);
                                  if  (lb !=  null  )
                                {
                                      var  mouseIndex = itemsSource.IndexOf( this .ItemContainerGenerator.ItemFromContainer((DependencyObject)lb)  as   SliderData);
                                      if  (mouseIndex <  0 ) mouseIndex =  0  ;
                                    itemsSource.Insert(mouseIndex, dataDrop);
                                }
                                  else  
                                {
                                    itemsSource.Add(dataDrop);
                                }
                                  this  .ScrollIntoView(dataDrop);
                            }
                              catch   { }
                        }
                    }
                    self  =  false  ;
                }
                  #endregion  
            }
              else  
            {
                  var  data = droppingCursor.Data  as   SPObjectData;
                  if  (data !=  null  )
                {
                      double  orientation = (thisParent.ItemContainerGenerator.ContainerFromItem(data)  as  ScatterViewItem) !=  null  ? (thisParent.ItemContainerGenerator.ContainerFromItem(data)  as  ScatterViewItem).ActualOrientation :  0  ;
                      if   (thisParent.Items.Contains(data))
                    {
                        thisParent.Items.Remove(data);
                    }
                    thisParent.Items.Add(data);
                      var  sviItem = thisParent.ItemContainerGenerator.ContainerFromItem(data)  as   ScatterViewItem;
                    sviItem.Center  =  Mouse.GetPosition(thisParent);
                    sviItem.Orientation  =  orientation;
                }
            }
        }

          #endregion 

         #region  Public Properties

         public   static   readonly  DependencyProperty DragDeleteProperty = DependencyProperty.Register( "  DragDelete  " ,  typeof ( bool ),  typeof (SPListBox),  new  PropertyMetadata( true  ));

          public   static   bool   GetDragDelete(DependencyObject element)
        {
              return  ( bool  )element.GetValue(DragDeleteProperty);
        }

          public   static   void  SetDragDelete(DependencyObject element,  bool   value)
        {
            element.SetValue(DragDeleteProperty, value);
        }

          public   Style DragCursorStyle
        {
              get  {  return   (Style)GetValue(DragCursorStyleProperty); }
              set   { SetValue(DragCursorStyleProperty, value); }
        }
          public   static   readonly  DependencyProperty DragCursorStyleProperty = 
            DependencyProperty.Register(  "  DragCursorStyle  " ,  typeof (Style),  typeof (SPListBox),  new  UIPropertyMetadata( null  ));


          public   int   MaxCount
        {
              get  {  return  ( int  )GetValue(MaxCountProperty); }
              set   { SetValue(MaxCountProperty, value); }
        }
          public   static   readonly  DependencyProperty MaxCountProperty = 
            DependencyProperty.Register(  "  MaxCount  " ,  typeof ( int ),  typeof (SPListBox),  new  PropertyMetadata( 20  ));


          #endregion 

         public  T Find<T>(DependencyObject v)  where   T : DependencyObject
        {
            DependencyObject res  =  v;
              while  (res !=  null  && !(res  is   T))
            {
                res  =  VisualTreeHelper.GetParent(res);
            }
              return   (T)res;
        }

    }
} 

 

分类:  WP7-迹`@柳燕

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于重写SurfaceListBox 完善DragDrop的详细内容...

  阅读:31次