diff --git a/Control/UserControls/PannelCard/LeftCardControl.xaml b/Control/UserControls/PannelCard/LeftCardControl.xaml
index e6df174..fb291ce 100644
--- a/Control/UserControls/PannelCard/LeftCardControl.xaml
+++ b/Control/UserControls/PannelCard/LeftCardControl.xaml
@@ -6,6 +6,7 @@
xmlns:local="clr-namespace:GeekDesk.Control.UserControls.PannelCard"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:cvt="clr-namespace:GeekDesk.Converts"
+ xmlns:cst="clr-namespace:GeekDesk.Constant"
xmlns:DraggAnimatedPanel="clr-namespace:DraggAnimatedPanel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
@@ -21,6 +22,11 @@
+
+
+
+
+
@@ -71,110 +77,149 @@
-->
-
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Control/UserControls/PannelCard/LeftCardControl.xaml.cs b/Control/UserControls/PannelCard/LeftCardControl.xaml.cs
index 095af92..c09c371 100644
--- a/Control/UserControls/PannelCard/LeftCardControl.xaml.cs
+++ b/Control/UserControls/PannelCard/LeftCardControl.xaml.cs
@@ -312,6 +312,9 @@ namespace GeekDesk.Control.UserControls.PannelCard
private void Menu_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (IS_EDIT) return;
+
+ MainWindow.mainWindow.RightCard.WrapCard.Visibility = Visibility.Collapsed;
+
//设置对应菜单的图标列表
if (MenuListBox.SelectedIndex == -1)
{
@@ -321,6 +324,7 @@ namespace GeekDesk.Control.UserControls.PannelCard
{
appData.AppConfig.SelectedMenuIcons = appData.MenuList[MenuListBox.SelectedIndex].IconList;
}
+ MainWindow.mainWindow.RightCard.WrapCard.Visibility = Visibility.Visible;
}
@@ -427,5 +431,35 @@ namespace GeekDesk.Control.UserControls.PannelCard
MenuListBox.SelectedIndex = index;
}
}
+
+
+ private void Menu_PreviewDragLeave(object sender, DragEventArgs e)
+ {
+ MyPoptip.IsOpen = false;
+ }
+
+ private void Menu_PreviewDragEnter(object sender, DragEventArgs e)
+ {
+ MenuInfo mi = (sender as ListBoxItem).DataContext as MenuInfo;
+ MyPoptipContent.Text = "移动至:" + mi.MenuName;
+ MyPoptip.VerticalOffset = 30;
+ MyPoptip.IsOpen = true;
+ }
+
+ private void Menu_MouseLeave(object sender, MouseEventArgs e)
+ {
+ MyPoptip.IsOpen = false;
+ }
+
+ private void Menu_Drop(object sender, DragEventArgs e)
+ {
+ MyPoptip.IsOpen = false;
+
+ MenuInfo mi = (sender as ListBoxItem).DataContext as MenuInfo;
+ IconInfo iconInfo = (IconInfo)e.Data.GetData(typeof(IconInfo));
+
+ appData.MenuList[MenuListBox.SelectedIndex].IconList.Remove(iconInfo);
+ appData.MenuList[MenuListBox.Items.IndexOf(mi)].IconList.Add(iconInfo);
+ }
}
}
diff --git a/Control/UserControls/PannelCard/RightCardControl.xaml b/Control/UserControls/PannelCard/RightCardControl.xaml
index 8974f54..127886e 100644
--- a/Control/UserControls/PannelCard/RightCardControl.xaml
+++ b/Control/UserControls/PannelCard/RightCardControl.xaml
@@ -19,15 +19,6 @@
-->
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -74,49 +88,52 @@
-
+
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
-
@@ -144,13 +161,14 @@
VerticalAlignment="Center"
Foreground="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.TextColor}"
Text="{Binding Name}"/>
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -172,7 +190,6 @@
-
dragMgr;
+
+ //private Thread dropCheckThread = null;
public RightCardControl()
{
InitializeComponent();
+ this.Loaded += RightCardControl_Loaded;
}
-
- #region 图标拖动
- DelegateCommand _swap;
- public DelegateCommand SwapCommand
+ private void RightCardControl_Loaded(object sender, RoutedEventArgs e)
{
- get
- {
- if (_swap == null)
- _swap = new DelegateCommand(
- (indexes) =>
- {
- DROP_ICON = true;
- if (appData.AppConfig.IconSortType != SortType.CUSTOM
- && (dropCheckThread == null || !dropCheckThread.IsAlive))
- {
- dropCheckThread = new Thread(() =>
- {
- do
- {
- DROP_ICON = false;
- Thread.Sleep(1000);
- } while (DROP_ICON);
-
- MainWindow.appData.AppConfig.IconSortType = SortType.CUSTOM;
- App.Current.Dispatcher.Invoke(() =>
- {
- if (MainWindow.mainWindow.Visibility == Visibility.Collapsed
- || MainWindow.mainWindow.Opacity != 1)
- {
- Growl.WarningGlobal("已将图标排序规则重置为自定义!");
- }
- else
- {
- Growl.Warning("已将图标排序规则重置为自定义!", "MainWindowGrowl");
- }
- });
- });
- dropCheckThread.Start();
- }
- int fromS = indexes[0];
- int to = indexes[1];
- ObservableCollection iconList = appData.MenuList[appData.AppConfig.SelectedMenuIndex].IconList;
- var elementSource = iconList[to];
- var dragged = iconList[fromS];
-
- iconList.Remove(dragged);
- iconList.Insert(to, dragged);
- }
- );
- return _swap;
- }
+ this.dragMgr = new ListBoxDragDropManager(this.IconListBox);
}
- #endregion 图标拖动
+
+ //#region 图标拖动
+ //DelegateCommand _swap;
+ //public DelegateCommand SwapCommand
+ //{
+ // get
+ // {
+ // if (_swap == null)
+ // _swap = new DelegateCommand(
+ // (indexes) =>
+ // {
+ // DROP_ICON = true;
+ // if (appData.AppConfig.IconSortType != SortType.CUSTOM
+ // && (dropCheckThread == null || !dropCheckThread.IsAlive))
+ // {
+ // dropCheckThread = new Thread(() =>
+ // {
+ // do
+ // {
+ // DROP_ICON = false;
+ // Thread.Sleep(1000);
+ // } while (DROP_ICON);
+
+ // MainWindow.appData.AppConfig.IconSortType = SortType.CUSTOM;
+ // App.Current.Dispatcher.Invoke(() =>
+ // {
+ // if (MainWindow.mainWindow.Visibility == Visibility.Collapsed
+ // || MainWindow.mainWindow.Opacity != 1)
+ // {
+ // Growl.WarningGlobal("已将图标排序规则重置为自定义!");
+ // }
+ // else
+ // {
+ // Growl.Warning("已将图标排序规则重置为自定义!", "MainWindowGrowl");
+ // }
+ // });
+ // });
+ // dropCheckThread.Start();
+ // }
+ // int fromS = indexes[0];
+ // int to = indexes[1];
+ // ObservableCollection iconList = appData.MenuList[appData.AppConfig.SelectedMenuIndex].IconList;
+ // var elementSource = iconList[to];
+ // var dragged = iconList[fromS];
+
+ // iconList.Remove(dragged);
+ // iconList.Insert(to, dragged);
+ // }
+ // );
+ // return _swap;
+ // }
+ //}
+
+ //#endregion 图标拖动
diff --git a/GeekDesk.csproj b/GeekDesk.csproj
index f7e4628..0949584 100644
--- a/GeekDesk.csproj
+++ b/GeekDesk.csproj
@@ -246,11 +246,13 @@
+
+
diff --git a/MainWindow.xaml b/MainWindow.xaml
index 1f8733d..08f2153 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -37,7 +37,7 @@
@@ -77,6 +77,8 @@
+
+
diff --git a/Util/DragAdorner.cs b/Util/DragAdorner.cs
new file mode 100644
index 0000000..432007b
--- /dev/null
+++ b/Util/DragAdorner.cs
@@ -0,0 +1,175 @@
+// Copyright (C) Josh Smith - January 2007
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Documents;
+using System.Windows;
+using System.Windows.Media;
+using System.Windows.Shapes;
+using System.Windows.Media.Animation;
+using System.Windows.Controls;
+
+namespace GeekDesk.Util
+{
+ ///
+ /// Renders a visual which can follow the mouse cursor,
+ /// such as during a drag-and-drop operation.
+ ///
+ public class DragAdorner : Adorner
+ {
+ #region Data
+
+ private Rectangle child = null;
+ private double offsetLeft = 0;
+ private double offsetTop = 0;
+
+ #endregion // Data
+
+ #region Constructor
+
+ ///
+ /// Initializes a new instance of DragVisualAdorner.
+ ///
+ /// The element being adorned.
+ /// The size of the adorner.
+ /// A brush to with which to paint the adorner.
+ public DragAdorner( UIElement adornedElement, Size size, Brush brush )
+ : base( adornedElement )
+ {
+ Rectangle rect = new Rectangle();
+ rect.Fill = brush;
+ rect.Width = size.Width;
+ rect.Height = size.Height;
+ rect.IsHitTestVisible = false;
+ this.child = rect;
+ }
+
+ #endregion // Constructor
+
+ #region Public Interface
+
+ #region GetDesiredTransform
+
+ ///
+ /// Override.
+ ///
+ ///
+ ///
+ public override GeneralTransform GetDesiredTransform( GeneralTransform transform )
+ {
+ GeneralTransformGroup result = new GeneralTransformGroup();
+ result.Children.Add( base.GetDesiredTransform( transform ) );
+ result.Children.Add( new TranslateTransform( this.offsetLeft, this.offsetTop ) );
+ return result;
+ }
+
+ #endregion // GetDesiredTransform
+
+ #region OffsetLeft
+
+ ///
+ /// Gets/sets the horizontal offset of the adorner.
+ ///
+ public double OffsetLeft
+ {
+ get { return this.offsetLeft; }
+ set
+ {
+ this.offsetLeft = value;
+ UpdateLocation();
+ }
+ }
+
+ #endregion // OffsetLeft
+
+ #region SetOffsets
+
+ ///
+ /// Updates the location of the adorner in one atomic operation.
+ ///
+ ///
+ ///
+ public void SetOffsets( double left, double top )
+ {
+ this.offsetLeft = left;
+ this.offsetTop = top;
+ this.UpdateLocation();
+ }
+
+ #endregion // SetOffsets
+
+ #region OffsetTop
+
+ ///
+ /// Gets/sets the vertical offset of the adorner.
+ ///
+ public double OffsetTop
+ {
+ get { return this.offsetTop; }
+ set
+ {
+ this.offsetTop = value;
+ UpdateLocation();
+ }
+ }
+
+ #endregion // OffsetTop
+
+ #endregion // Public Interface
+
+ #region Protected Overrides
+
+ ///
+ /// Override.
+ ///
+ ///
+ ///
+ protected override Size MeasureOverride( Size constraint )
+ {
+ this.child.Measure( constraint );
+ return this.child.DesiredSize;
+ }
+
+ ///
+ /// Override.
+ ///
+ ///
+ ///
+ protected override Size ArrangeOverride( Size finalSize )
+ {
+ this.child.Arrange( new Rect( finalSize ) );
+ return finalSize;
+ }
+
+ ///
+ /// Override.
+ ///
+ ///
+ ///
+ protected override Visual GetVisualChild( int index )
+ {
+ return this.child;
+ }
+
+ ///
+ /// Override. Always returns 1.
+ ///
+ protected override int VisualChildrenCount
+ {
+ get { return 1; }
+ }
+
+ #endregion // Protected Overrides
+
+ #region Private Helpers
+
+ private void UpdateLocation()
+ {
+ AdornerLayer adornerLayer = this.Parent as AdornerLayer;
+ if( adornerLayer != null )
+ adornerLayer.Update( this.AdornedElement );
+ }
+
+ #endregion // Private Helpers
+ }
+}
\ No newline at end of file
diff --git a/Util/ListBoxDragDropManager.cs b/Util/ListBoxDragDropManager.cs
new file mode 100644
index 0000000..5772529
--- /dev/null
+++ b/Util/ListBoxDragDropManager.cs
@@ -0,0 +1,892 @@
+// Copyright (C) Josh Smith - January 2007
+using System;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Documents;
+using System.Windows.Media;
+using System.Windows.Input;
+using GeekDesk.Util;
+using GeekDesk.Constant;
+using HandyControl.Controls;
+
+namespace GeekDesk.Util
+{
+ #region ListBoxDragDropManager
+
+ ///
+ /// Manages the dragging and dropping of ListBoxItems in a ListBox.
+ /// The ItemType type parameter indicates the type of the objects in
+ /// the ListBox's items source. The ListBox's ItemsSource must be
+ /// set to an instance of ObservableCollection of ItemType, or an
+ /// Exception will be thrown.
+ ///
+ /// The type of the ListBox's items.
+ public class ListBoxDragDropManager where ItemType : class
+ {
+ #region Data
+
+ bool canInitiateDrag;
+ DragAdorner dragAdorner;
+ double dragAdornerOpacity;
+ int indexToSelect;
+ bool isDragInProgress;
+ ItemType itemUnderDragCursor;
+ ListBox listBox;
+ Point ptMouseDown;
+ bool showDragAdorner;
+
+ #endregion // Data
+
+ #region Constructors
+
+ ///
+ /// Initializes a new instance of ListBoxDragManager.
+ ///
+ public ListBoxDragDropManager()
+ {
+ this.canInitiateDrag = false;
+ this.dragAdornerOpacity = 0.7;
+ this.indexToSelect = -1;
+ this.showDragAdorner = true;
+ }
+
+ ///
+ /// Initializes a new instance of ListBoxDragManager.
+ ///
+ ///
+ public ListBoxDragDropManager( ListBox listBox )
+ : this()
+ {
+ this.ListBox = listBox;
+ }
+
+ ///
+ /// Initializes a new instance of ListBoxDragManager.
+ ///
+ ///
+ ///
+ public ListBoxDragDropManager( ListBox listBox, double dragAdornerOpacity )
+ : this( listBox )
+ {
+ this.DragAdornerOpacity = dragAdornerOpacity;
+ }
+
+ ///
+ /// Initializes a new instance of ListBoxDragManager.
+ ///
+ ///
+ ///
+ public ListBoxDragDropManager( ListBox listBox, bool showDragAdorner )
+ : this( listBox )
+ {
+ this.ShowDragAdorner = showDragAdorner;
+ }
+
+ #endregion // Constructors
+
+ #region Public Interface
+
+ #region DragAdornerOpacity
+
+ ///
+ /// Gets/sets the opacity of the drag adorner. This property has no
+ /// effect if ShowDragAdorner is false. The default value is 0.7
+ ///
+ public double DragAdornerOpacity
+ {
+ get { return this.dragAdornerOpacity; }
+ set
+ {
+ if( this.IsDragInProgress )
+ throw new InvalidOperationException( "Cannot set the DragAdornerOpacity property during a drag operation." );
+
+ if( value < 0.0 || value > 1.0 )
+ throw new ArgumentOutOfRangeException( "DragAdornerOpacity", value, "Must be between 0 and 1." );
+
+ this.dragAdornerOpacity = value;
+ }
+ }
+
+ #endregion // DragAdornerOpacity
+
+ #region IsDragInProgress
+
+ ///
+ /// Returns true if there is currently a drag operation being managed.
+ ///
+ public bool IsDragInProgress
+ {
+ get { return this.isDragInProgress; }
+ private set { this.isDragInProgress = value; }
+ }
+
+ #endregion // IsDragInProgress
+
+ #region ListBox
+
+ ///
+ /// Gets/sets the ListBox whose dragging is managed. This property
+ /// can be set to null, to prevent drag management from occuring. If
+ /// the ListBox's AllowDrop property is false, it will be set to true.
+ ///
+ public ListBox ListBox
+ {
+ get { return listBox; }
+ set
+ {
+ if( this.IsDragInProgress )
+ throw new InvalidOperationException( "Cannot set the ListBox property during a drag operation." );
+
+ if( this.listBox != null )
+ {
+ #region Unhook Events
+
+ this.listBox.PreviewMouseLeftButtonDown -= LIstBox_PreviewMouseLeftButtonDown;
+ this.listBox.PreviewMouseMove -= LIstBox_PreviewMouseMove;
+ this.listBox.DragOver -= LIstBox_DragOver;
+ this.listBox.DragLeave -= LIstBox_DragLeave;
+ this.listBox.DragEnter -= LIstBox_DragEnter;
+ this.listBox.Drop -= LIstBox_Drop;
+
+ #endregion // Unhook Events
+ }
+
+ this.listBox = value;
+
+ if( this.listBox != null )
+ {
+ if( !this.listBox.AllowDrop )
+ this.listBox.AllowDrop = true;
+
+ #region Hook Events
+
+ this.listBox.PreviewMouseLeftButtonDown += LIstBox_PreviewMouseLeftButtonDown;
+ this.listBox.PreviewMouseMove += LIstBox_PreviewMouseMove;
+ this.listBox.DragOver += LIstBox_DragOver;
+ this.listBox.DragLeave += LIstBox_DragLeave;
+ this.listBox.DragEnter += LIstBox_DragEnter;
+ this.listBox.Drop += LIstBox_Drop;
+
+ #endregion // Hook Events
+ }
+ }
+ }
+
+ #endregion // ListBox
+
+ #region ProcessDrop [event]
+
+ ///
+ /// Raised when a drop occurs. By default the dropped item will be moved
+ /// to the target index. Handle this event if relocating the dropped item
+ /// requires custom behavior. Note, if this event is handled the default
+ /// item dropping logic will not occur.
+ ///
+ public event EventHandler> ProcessDrop;
+
+ #endregion // ProcessDrop [event]
+
+ #region ShowDragAdorner
+
+ ///
+ /// Gets/sets whether a visual representation of the ListBoxItem being dragged
+ /// follows the mouse cursor during a drag operation. The default value is true.
+ ///
+ public bool ShowDragAdorner
+ {
+ get { return this.showDragAdorner; }
+ set
+ {
+ if( this.IsDragInProgress )
+ throw new InvalidOperationException( "Cannot set the ShowDragAdorner property during a drag operation." );
+
+ this.showDragAdorner = value;
+ }
+ }
+
+ #endregion // ShowDragAdorner
+
+ #endregion // Public Interface
+
+ #region Event Handling Methods
+
+ #region LIstBox_PreviewMouseLeftButtonDown
+
+ void LIstBox_PreviewMouseLeftButtonDown( object sender, MouseButtonEventArgs e )
+ {
+ if( this.IsMouseOverScrollbar )
+ {
+ // 4/13/2007 - Set the flag to false when cursor is over scrollbar.
+ this.canInitiateDrag = false;
+ return;
+ }
+
+ int index = this.IndexUnderDragCursor;
+ this.canInitiateDrag = index > -1;
+
+ if( this.canInitiateDrag )
+ {
+ // Remember the location and index of the ListBoxItem the user clicked on for later.
+ this.ptMouseDown = MouseUtil.GetMousePosition();
+ //this.ptMouseDown = MouseUtil.GetMousePosition( this.listBox );
+ this.indexToSelect = index;
+ }
+ else
+ {
+ this.ptMouseDown = new Point( -10000, -10000 );
+ this.indexToSelect = -1;
+ }
+ }
+
+ #endregion // LIstBox_PreviewMouseLeftButtonDown
+
+ #region LIstBox_PreviewMouseMove
+
+ void LIstBox_PreviewMouseMove( object sender, MouseEventArgs e )
+ {
+ if( !this.CanStartDragOperation )
+ return;
+
+ // Select the item the user clicked on.
+ if( this.listBox.SelectedIndex != this.indexToSelect )
+ this.listBox.SelectedIndex = this.indexToSelect;
+
+ // If the item at the selected index is null, there's nothing
+ // we can do, so just return;
+ if( this.listBox.SelectedItem == null )
+ return;
+
+ ListBoxItem itemToDrag = this.GetListBoxItem( this.listBox.SelectedIndex );
+ if( itemToDrag == null )
+ return;
+
+ AdornerLayer adornerLayer = this.ShowDragAdornerResolved ? this.InitializeAdornerLayer( itemToDrag ) : null;
+
+ this.InitializeDragOperation( itemToDrag );
+ this.PerformDragOperation();
+ this.FinishDragOperation( itemToDrag, adornerLayer );
+ }
+
+ #endregion // LIstBox_PreviewMouseMove
+
+ #region LIstBox_DragOver
+
+ void LIstBox_DragOver( object sender, DragEventArgs e )
+ {
+ e.Effects = DragDropEffects.Move;
+
+ if ( this.ShowDragAdornerResolved )
+ this.UpdateDragAdornerLocation();
+
+ // Update the item which is known to be currently under the drag cursor.
+ int index = this.IndexUnderDragCursor;
+ this.ItemUnderDragCursor = index < 0 ? null : this.ListBox.Items[index] as ItemType;
+ }
+
+ #endregion // LIstBox_DragOver
+
+ #region LIstBox_DragLeave
+
+ void LIstBox_DragLeave( object sender, DragEventArgs e )
+ {
+ if( !this.IsMouseOver( this.listBox ) )
+ {
+ if( this.ItemUnderDragCursor != null )
+ this.ItemUnderDragCursor = null;
+
+ if( this.dragAdorner != null )
+ this.dragAdorner.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ #endregion // LIstBox_DragLeave
+
+ #region LIstBox_DragEnter
+
+ void LIstBox_DragEnter( object sender, DragEventArgs e )
+ {
+ if( this.dragAdorner != null && this.dragAdorner.Visibility != Visibility.Visible )
+ {
+ // Update the location of the adorner and then show it.
+ this.UpdateDragAdornerLocation();
+ this.dragAdorner.Visibility = Visibility.Visible;
+ }
+ }
+
+ #endregion // LIstBox_DragEnter
+
+ #region LIstBox_Drop
+
+ void LIstBox_Drop( object sender, DragEventArgs e )
+ {
+ if( this.ItemUnderDragCursor != null )
+ this.ItemUnderDragCursor = null;
+
+ e.Effects = DragDropEffects.None;
+
+ if( !e.Data.GetDataPresent( typeof( ItemType ) ) )
+ return;
+
+ // Get the data object which was dropped.
+ ItemType data = e.Data.GetData( typeof( ItemType ) ) as ItemType;
+ if( data == null )
+ return;
+
+ // Get the ObservableCollection which contains the dropped data object.
+ ObservableCollection itemsSource = this.listBox.ItemsSource as ObservableCollection;
+ if( itemsSource == null )
+ throw new Exception(
+ "A ListBox managed by ListBoxDragManager must have its ItemsSource set to an ObservableCollection." );
+
+ int oldIndex = itemsSource.IndexOf( data );
+ int newIndex = this.IndexUnderDragCursor;
+
+ if( newIndex < 0 )
+ {
+ // The drag started somewhere else, and our ListBox is empty
+ // so make the new item the first in the list.
+ if( itemsSource.Count == 0 )
+ newIndex = 0;
+
+ // The drag started somewhere else, but our ListBox has items
+ // so make the new item the last in the list.
+ else if( oldIndex < 0 )
+ newIndex = itemsSource.Count;
+
+ // The user is trying to drop an item from our ListBox into
+ // our ListBox, but the mouse is not over an item, so don't
+ // let them drop it.
+ else
+ return;
+ }
+
+ // Dropping an item back onto itself is not considered an actual 'drop'.
+ if( oldIndex == newIndex )
+ return;
+
+ if( this.ProcessDrop != null )
+ {
+ // Let the client code process the drop.
+ ProcessDropEventArgs args = new ProcessDropEventArgs( itemsSource, data, oldIndex, newIndex, e.AllowedEffects );
+ this.ProcessDrop( this, args );
+ e.Effects = args.Effects;
+ }
+ else
+ {
+ // Move the dragged data object from it's original index to the
+ // new index (according to where the mouse cursor is). If it was
+ // not previously in the ListBox, then insert the item.
+ if( oldIndex > -1 )
+ {
+ // ⲿҵ
+ itemsSource.Move(oldIndex, newIndex);
+ if (MainWindow.appData.AppConfig.IconSortType != SortType.CUSTOM)
+ {
+ MainWindow.appData.AppConfig.IconSortType = SortType.CUSTOM;
+ if (MainWindow.mainWindow.Visibility == Visibility.Collapsed
+ || MainWindow.mainWindow.Opacity != 1)
+ {
+ Growl.WarningGlobal("ѽͼΪԶ!");
+ }
+ else
+ {
+ Growl.Warning("ѽͼΪԶ!", "MainWindowGrowl");
+ }
+ }
+ }
+ else
+ {
+ itemsSource.Insert(newIndex, data);
+ }
+
+ // Set the Effects property so that the call to DoDragDrop will return 'Move'.
+ e.Effects = DragDropEffects.Move;
+ }
+ }
+
+ #endregion // LIstBox_Drop
+
+ #endregion // Event Handling Methods
+
+ #region Private Helpers
+
+ #region CanStartDragOperation
+
+ bool CanStartDragOperation
+ {
+ get
+ {
+ if( Mouse.LeftButton != MouseButtonState.Pressed )
+ return false;
+
+ if( !this.canInitiateDrag )
+ return false;
+
+ if( this.indexToSelect == -1 )
+ return false;
+
+ if( !this.HasCursorLeftDragThreshold )
+ return false;
+
+ return true;
+ }
+ }
+
+ #endregion // CanStartDragOperation
+
+ #region FinishDragOperation
+
+ void FinishDragOperation( ListBoxItem draggedItem, AdornerLayer adornerLayer )
+ {
+ // Let the ListBoxItem know that it is not being dragged anymore.
+ ListBoxItemDragState.SetIsBeingDragged( draggedItem, false );
+
+ this.IsDragInProgress = false;
+
+ if( this.ItemUnderDragCursor != null )
+ this.ItemUnderDragCursor = null;
+
+ // Remove the drag adorner from the adorner layer.
+ if( adornerLayer != null )
+ {
+ adornerLayer.Remove( this.dragAdorner );
+ this.dragAdorner = null;
+ }
+ }
+
+ #endregion // FinishDragOperation
+
+ #region GetListBoxItem
+
+ ListBoxItem GetListBoxItem( int index )
+ {
+ if( this.listBox.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated )
+ return null;
+
+ return this.listBox.ItemContainerGenerator.ContainerFromIndex( index ) as ListBoxItem;
+ }
+
+ ListBoxItem GetListBoxItem( ItemType dataItem )
+ {
+ if( this.listBox.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated )
+ return null;
+
+ return this.listBox.ItemContainerGenerator.ContainerFromItem( dataItem ) as ListBoxItem;
+ }
+
+ #endregion // GetListBoxItem
+
+ #region HasCursorLeftDragThreshold
+
+ bool HasCursorLeftDragThreshold
+ {
+ get
+ {
+ if( this.indexToSelect < 0 )
+ return false;
+
+ ListBoxItem item = this.GetListBoxItem( this.indexToSelect );
+ Rect bounds = VisualTreeHelper.GetDescendantBounds( item );
+ Point ptInItem = this.listBox.TranslatePoint( this.ptMouseDown, item );
+
+ // In case the cursor is at the very top or bottom of the ListBoxItem
+ // we want to make the vertical threshold very small so that dragging
+ // over an adjacent item does not select it.
+ double topOffset = Math.Abs( ptInItem.Y );
+ double btmOffset = Math.Abs( bounds.Height - ptInItem.Y );
+ double vertOffset = Math.Min( topOffset, btmOffset );
+
+ double width = SystemParameters.MinimumHorizontalDragDistance * 2;
+ double height = Math.Min( SystemParameters.MinimumVerticalDragDistance, vertOffset ) * 2;
+ Size szThreshold = new Size( width, height );
+
+ Rect rect = new Rect( this.ptMouseDown, szThreshold );
+ rect.Offset( szThreshold.Width / -2, szThreshold.Height / -2 );
+ //Point ptInListBox = MouseUtil.GetMousePosition(this.listBox);
+ Point ptInListBox = MouseUtil.GetMousePosition();
+ return !rect.Contains( ptInListBox );
+ }
+ }
+
+ #endregion // HasCursorLeftDragThreshold
+
+ #region IndexUnderDragCursor
+
+ ///
+ /// Returns the index of the ListBoxItem underneath the
+ /// drag cursor, or -1 if the cursor is not over an item.
+ ///
+ int IndexUnderDragCursor
+ {
+ get
+ {
+ int index = -1;
+ for( int i = 0; i < this.listBox.Items.Count; ++i )
+ {
+ ListBoxItem item = this.GetListBoxItem( i );
+ if( this.IsMouseOver( item ) )
+ {
+ index = i;
+ break;
+ }
+ }
+ return index;
+ }
+ }
+
+ #endregion // IndexUnderDragCursor
+
+ #region InitializeAdornerLayer
+
+ AdornerLayer InitializeAdornerLayer( ListBoxItem itemToDrag )
+ {
+ // Create a brush which will paint the ListBoxItem onto
+ // a visual in the adorner layer.
+ VisualBrush brush = new VisualBrush( itemToDrag );
+
+ // Create an element which displays the source item while it is dragged.
+ this.dragAdorner = new DragAdorner( this.listBox, itemToDrag.RenderSize, brush );
+
+ // Set the drag adorner's opacity.
+ this.dragAdorner.Opacity = this.DragAdornerOpacity;
+
+ AdornerLayer layer = AdornerLayer.GetAdornerLayer( this.listBox );
+ layer.Add( dragAdorner );
+
+ // Save the location of the cursor when the left mouse button was pressed.
+ this.ptMouseDown = MouseUtil.GetMousePosition(this.listBox);
+ //this.ptMouseDown = MouseUtil.GetMousePosition();
+
+ return layer;
+ }
+
+ #endregion // InitializeAdornerLayer
+
+ #region InitializeDragOperation
+
+ void InitializeDragOperation( ListBoxItem itemToDrag )
+ {
+ // Set some flags used during the drag operation.
+ this.IsDragInProgress = true;
+ this.canInitiateDrag = false;
+
+ // Let the ListBoxItem know that it is being dragged.
+ ListBoxItemDragState.SetIsBeingDragged( itemToDrag, true );
+ }
+
+ #endregion // InitializeDragOperation
+
+ #region IsMouseOver
+
+ bool IsMouseOver( Visual target )
+ {
+ // We need to use MouseUtil to figure out the cursor
+ // coordinates because, during a drag-drop operation, the WPF
+ // mechanisms for getting the coordinates behave strangely.
+
+ Rect bounds = VisualTreeHelper.GetDescendantBounds( target );
+ Point mousePos = MouseUtil.GetMousePosition( target );
+ return bounds.Contains( mousePos );
+ }
+
+ #endregion // IsMouseOver
+
+ #region IsMouseOverScrollbar
+
+ ///
+ /// Returns true if the mouse cursor is over a scrollbar in the ListBox.
+ ///
+ bool IsMouseOverScrollbar
+ {
+ get
+ {
+ Point ptMouse = MouseUtil.GetMousePosition( this.listBox );
+ HitTestResult res = VisualTreeHelper.HitTest( this.listBox, ptMouse );
+ if( res == null )
+ return false;
+
+ DependencyObject depObj = res.VisualHit;
+ while( depObj != null )
+ {
+ if( depObj is ScrollBar )
+ return true;
+
+ // VisualTreeHelper works with objects of type Visual or Visual3D.
+ // If the current object is not derived from Visual or Visual3D,
+ // then use the LogicalTreeHelper to find the parent element.
+ if( depObj is Visual || depObj is System.Windows.Media.Media3D.Visual3D )
+ depObj = VisualTreeHelper.GetParent( depObj );
+ else
+ depObj = LogicalTreeHelper.GetParent( depObj );
+ }
+
+ return false;
+ }
+ }
+
+ #endregion // IsMouseOverScrollbar
+
+ #region ItemUnderDragCursor
+
+ ItemType ItemUnderDragCursor
+ {
+ get { return this.itemUnderDragCursor; }
+ set
+ {
+ if( this.itemUnderDragCursor == value )
+ return;
+
+ // The first pass handles the previous item under the cursor.
+ // The second pass handles the new one.
+ for( int i = 0; i < 2; ++i )
+ {
+ if( i == 1 )
+ this.itemUnderDragCursor = value;
+
+ if( this.itemUnderDragCursor != null )
+ {
+ ListBoxItem listBoxItem = this.GetListBoxItem( this.itemUnderDragCursor );
+ if( listBoxItem != null )
+ ListBoxItemDragState.SetIsUnderDragCursor( listBoxItem, i == 1 );
+ }
+ }
+ }
+ }
+
+ #endregion // ItemUnderDragCursor
+
+ #region PerformDragOperation
+
+ void PerformDragOperation()
+ {
+ ItemType selectedItem = this.listBox.SelectedItem as ItemType;
+ DragDropEffects allowedEffects = DragDropEffects.Move | DragDropEffects.Move | DragDropEffects.Link;
+ if( DragDrop.DoDragDrop( this.listBox, selectedItem, allowedEffects ) != DragDropEffects.None )
+ {
+ // The item was dropped into a new location,
+ // so make it the new selected item.
+ this.listBox.SelectedItem = selectedItem;
+ }
+ }
+
+ #endregion // PerformDragOperation
+
+ #region ShowDragAdornerResolved
+
+ bool ShowDragAdornerResolved
+ {
+ get { return this.ShowDragAdorner && this.DragAdornerOpacity > 0.0; }
+ }
+
+ #endregion // ShowDragAdornerResolved
+
+ #region UpdateDragAdornerLocation
+
+ void UpdateDragAdornerLocation()
+ {
+ if( this.dragAdorner != null )
+ {
+ //Point ptCursor = MouseUtil.GetMousePosition(this.ListBox);
+
+
+ Point ptCursor = MouseUtil.GetMousePosition(this.ListBox);
+
+ //double left = ptCursor.X - this.ptMouseDown.X;
+ //double left2 = ptCursor.X;
+
+ ListBoxItem itemBeingDragged = this.GetListBoxItem(this.indexToSelect);
+
+ // 4/13/2007 - Made the top offset relative to the item being dragged.
+ Point itemLoc = itemBeingDragged.TranslatePoint( new Point( 0, 0 ), this.ListBox );
+ double top = itemLoc.Y + ptCursor.Y - this.ptMouseDown.Y;
+ double left = itemLoc.X + ptCursor.X - this.ptMouseDown.X;
+
+ this.dragAdorner.SetOffsets(left, top );
+ }
+ }
+
+ #endregion // UpdateDragAdornerLocation
+
+ #endregion // Private Helpers
+ }
+
+ #endregion // ListBoxDragDropManager
+
+ #region ListBoxItemDragState
+
+ ///
+ /// Exposes attached properties used in conjunction with the ListBoxDragDropManager class.
+ /// Those properties can be used to allow triggers to modify the appearance of ListBoxItems
+ /// in a ListBox during a drag-drop operation.
+ ///
+ public static class ListBoxItemDragState
+ {
+ #region IsBeingDragged
+
+ ///
+ /// Identifies the ListBoxItemDragState's IsBeingDragged attached property.
+ /// This field is read-only.
+ ///
+ public static readonly DependencyProperty IsBeingDraggedProperty =
+ DependencyProperty.RegisterAttached(
+ "IsBeingDragged",
+ typeof( bool ),
+ typeof( ListBoxItemDragState ),
+ new UIPropertyMetadata( false ) );
+
+ ///
+ /// Returns true if the specified ListBoxItem is being dragged, else false.
+ ///
+ /// The ListBoxItem to check.
+ public static bool GetIsBeingDragged( ListBoxItem item )
+ {
+ return (bool)item.GetValue( IsBeingDraggedProperty );
+ }
+
+ ///
+ /// Sets the IsBeingDragged attached property for the specified ListBoxItem.
+ ///
+ /// The ListBoxItem to set the property on.
+ /// Pass true if the element is being dragged, else false.
+ internal static void SetIsBeingDragged( ListBoxItem item, bool value )
+ {
+ item.SetValue( IsBeingDraggedProperty, value );
+ }
+
+ #endregion // IsBeingDragged
+
+ #region IsUnderDragCursor
+
+ ///
+ /// Identifies the ListBoxItemDragState's IsUnderDragCursor attached property.
+ /// This field is read-only.
+ ///
+ public static readonly DependencyProperty IsUnderDragCursorProperty =
+ DependencyProperty.RegisterAttached(
+ "IsUnderDragCursor",
+ typeof( bool ),
+ typeof( ListBoxItemDragState ),
+ new UIPropertyMetadata( false ) );
+
+ ///
+ /// Returns true if the specified ListBoxItem is currently underneath the cursor
+ /// during a drag-drop operation, else false.
+ ///
+ /// The ListBoxItem to check.
+ public static bool GetIsUnderDragCursor( ListBoxItem item )
+ {
+ return (bool)item.GetValue( IsUnderDragCursorProperty );
+ }
+
+ ///
+ /// Sets the IsUnderDragCursor attached property for the specified ListBoxItem.
+ ///
+ /// The ListBoxItem to set the property on.
+ /// Pass true if the element is underneath the drag cursor, else false.
+ internal static void SetIsUnderDragCursor( ListBoxItem item, bool value )
+ {
+ item.SetValue( IsUnderDragCursorProperty, value );
+ }
+
+ #endregion // IsUnderDragCursor
+ }
+
+ #endregion // ListBoxItemDragState
+
+ #region ProcessDropEventArgs
+
+ ///
+ /// Event arguments used by the ListBoxDragDropManager.ProcessDrop event.
+ ///
+ /// The type of data object being dropped.
+ public class ProcessDropEventArgs : EventArgs where ItemType : class
+ {
+ #region Data
+
+ ObservableCollection itemsSource;
+ ItemType dataItem;
+ int oldIndex;
+ int newIndex;
+ DragDropEffects allowedEffects = DragDropEffects.None;
+ DragDropEffects effects = DragDropEffects.None;
+
+ #endregion // Data
+
+ #region Constructor
+
+ internal ProcessDropEventArgs(
+ ObservableCollection itemsSource,
+ ItemType dataItem,
+ int oldIndex,
+ int newIndex,
+ DragDropEffects allowedEffects )
+ {
+ this.itemsSource = itemsSource;
+ this.dataItem = dataItem;
+ this.oldIndex = oldIndex;
+ this.newIndex = newIndex;
+ this.allowedEffects = allowedEffects;
+ }
+
+ #endregion // Constructor
+
+ #region Public Properties
+
+ ///
+ /// The items source of the ListBox where the drop occurred.
+ ///
+ public ObservableCollection ItemsSource
+ {
+ get { return this.itemsSource; }
+ }
+
+ ///
+ /// The data object which was dropped.
+ ///
+ public ItemType DataItem
+ {
+ get { return this.dataItem; }
+ }
+
+ ///
+ /// The current index of the data item being dropped, in the ItemsSource collection.
+ ///
+ public int OldIndex
+ {
+ get { return this.oldIndex; }
+ }
+
+ ///
+ /// The target index of the data item being dropped, in the ItemsSource collection.
+ ///
+ public int NewIndex
+ {
+ get { return this.newIndex; }
+ }
+
+ ///
+ /// The drag drop effects allowed to be performed.
+ ///
+ public DragDropEffects AllowedEffects
+ {
+ get { return allowedEffects; }
+ }
+
+ ///
+ /// The drag drop effect(s) performed on the dropped item.
+ ///
+ public DragDropEffects Effects
+ {
+ get { return effects; }
+ set { effects = value; }
+ }
+
+ #endregion // Public Properties
+ }
+
+ #endregion // ProcessDropEventArgs
+}
\ No newline at end of file
diff --git a/Util/MouseUtil.cs b/Util/MouseUtil.cs
index 6197053..cd9716b 100644
--- a/Util/MouseUtil.cs
+++ b/Util/MouseUtil.cs
@@ -1,6 +1,7 @@
using System;
using System.Runtime.InteropServices;
using System.Windows;
+using System.Windows.Media;
namespace GeekDesk.Util
{
@@ -27,5 +28,27 @@ namespace GeekDesk.Util
GetCursorPos(ref w32Mouse);
return new Point(w32Mouse.X, w32Mouse.Y);
}
+
+
+ public static Point GetMousePosition(Visual relativeTo)
+ {
+ Win32Point mouse = new Win32Point();
+ GetCursorPos(ref mouse);
+
+ // Using PointFromScreen instead of Dan Crevier's code (commented out below)
+ // is a bug fix created by William J. Roberts. Read his comments about the fix
+ // here: http://www.codeproject.com/useritems/ListViewDragDropManager.asp?msg=1911611#xx1911611xx
+ return relativeTo.PointFromScreen(new Point((double)mouse.X, (double)mouse.Y));
+
+ #region Commented Out
+ //System.Windows.Interop.HwndSource presentationSource =
+ // (System.Windows.Interop.HwndSource)PresentationSource.FromVisual( relativeTo );
+ //ScreenToClient( presentationSource.Handle, ref mouse );
+ //GeneralTransform transform = relativeTo.TransformToAncestor( presentationSource.RootVisual );
+ //Point offset = transform.Transform( new Point( 0, 0 ) );
+ //return new Point( mouse.X - offset.X, mouse.Y - offset.Y );
+ #endregion // Commented Out
+ }
+
}
}