123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892 |
- // 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
- /// <summary>
- /// 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.
- /// </summary>
- /// <typeparam name="ItemType">The type of the ListBox's items.</typeparam>
- public class ListBoxDragDropManager<ItemType> 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
- /// <summary>
- /// Initializes a new instance of ListBoxDragManager.
- /// </summary>
- public ListBoxDragDropManager()
- {
- this.canInitiateDrag = false;
- this.dragAdornerOpacity = 0.7;
- this.indexToSelect = -1;
- this.showDragAdorner = true;
- }
- /// <summary>
- /// Initializes a new instance of ListBoxDragManager.
- /// </summary>
- /// <param name="listBox"></param>
- public ListBoxDragDropManager( ListBox listBox )
- : this()
- {
- this.ListBox = listBox;
- }
- /// <summary>
- /// Initializes a new instance of ListBoxDragManager.
- /// </summary>
- /// <param name="listBox"></param>
- /// <param name="dragAdornerOpacity"></param>
- public ListBoxDragDropManager( ListBox listBox, double dragAdornerOpacity )
- : this( listBox )
- {
- this.DragAdornerOpacity = dragAdornerOpacity;
- }
- /// <summary>
- /// Initializes a new instance of ListBoxDragManager.
- /// </summary>
- /// <param name="listBox"></param>
- /// <param name="showDragAdorner"></param>
- public ListBoxDragDropManager( ListBox listBox, bool showDragAdorner )
- : this( listBox )
- {
- this.ShowDragAdorner = showDragAdorner;
- }
- #endregion // Constructors
- #region Public Interface
- #region DragAdornerOpacity
- /// <summary>
- /// Gets/sets the opacity of the drag adorner. This property has no
- /// effect if ShowDragAdorner is false. The default value is 0.7
- /// </summary>
- 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
- /// <summary>
- /// Returns true if there is currently a drag operation being managed.
- /// </summary>
- public bool IsDragInProgress
- {
- get { return this.isDragInProgress; }
- private set { this.isDragInProgress = value; }
- }
- #endregion // IsDragInProgress
- #region ListBox
- /// <summary>
- /// 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.
- /// </summary>
- 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]
- /// <summary>
- /// 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.
- /// </summary>
- public event EventHandler<ProcessDropEventArgs<ItemType>> ProcessDrop;
- #endregion // ProcessDrop [event]
- #region ShowDragAdorner
- /// <summary>
- /// Gets/sets whether a visual representation of the ListBoxItem being dragged
- /// follows the mouse cursor during a drag operation. The default value is true.
- /// </summary>
- 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<ItemType> which contains the dropped data object.
- ObservableCollection<ItemType> itemsSource = this.listBox.ItemsSource as ObservableCollection<ItemType>;
- if( itemsSource == null )
- throw new Exception(
- "A ListBox managed by ListBoxDragManager must have its ItemsSource set to an ObservableCollection<ItemType>." );
- 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<ItemType> args = new ProcessDropEventArgs<ItemType>( 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
- /// <summary>
- /// Returns the index of the ListBoxItem underneath the
- /// drag cursor, or -1 if the cursor is not over an item.
- /// </summary>
- 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
- /// <summary>
- /// Returns true if the mouse cursor is over a scrollbar in the ListBox.
- /// </summary>
- 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
- /// <summary>
- /// 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.
- /// </summary>
- public static class ListBoxItemDragState
- {
- #region IsBeingDragged
- /// <summary>
- /// Identifies the ListBoxItemDragState's IsBeingDragged attached property.
- /// This field is read-only.
- /// </summary>
- public static readonly DependencyProperty IsBeingDraggedProperty =
- DependencyProperty.RegisterAttached(
- "IsBeingDragged",
- typeof( bool ),
- typeof( ListBoxItemDragState ),
- new UIPropertyMetadata( false ) );
- /// <summary>
- /// Returns true if the specified ListBoxItem is being dragged, else false.
- /// </summary>
- /// <param name="item">The ListBoxItem to check.</param>
- public static bool GetIsBeingDragged( ListBoxItem item )
- {
- return (bool)item.GetValue( IsBeingDraggedProperty );
- }
- /// <summary>
- /// Sets the IsBeingDragged attached property for the specified ListBoxItem.
- /// </summary>
- /// <param name="item">The ListBoxItem to set the property on.</param>
- /// <param name="value">Pass true if the element is being dragged, else false.</param>
- internal static void SetIsBeingDragged( ListBoxItem item, bool value )
- {
- item.SetValue( IsBeingDraggedProperty, value );
- }
- #endregion // IsBeingDragged
- #region IsUnderDragCursor
- /// <summary>
- /// Identifies the ListBoxItemDragState's IsUnderDragCursor attached property.
- /// This field is read-only.
- /// </summary>
- public static readonly DependencyProperty IsUnderDragCursorProperty =
- DependencyProperty.RegisterAttached(
- "IsUnderDragCursor",
- typeof( bool ),
- typeof( ListBoxItemDragState ),
- new UIPropertyMetadata( false ) );
- /// <summary>
- /// Returns true if the specified ListBoxItem is currently underneath the cursor
- /// during a drag-drop operation, else false.
- /// </summary>
- /// <param name="item">The ListBoxItem to check.</param>
- public static bool GetIsUnderDragCursor( ListBoxItem item )
- {
- return (bool)item.GetValue( IsUnderDragCursorProperty );
- }
- /// <summary>
- /// Sets the IsUnderDragCursor attached property for the specified ListBoxItem.
- /// </summary>
- /// <param name="item">The ListBoxItem to set the property on.</param>
- /// <param name="value">Pass true if the element is underneath the drag cursor, else false.</param>
- internal static void SetIsUnderDragCursor( ListBoxItem item, bool value )
- {
- item.SetValue( IsUnderDragCursorProperty, value );
- }
- #endregion // IsUnderDragCursor
- }
- #endregion // ListBoxItemDragState
- #region ProcessDropEventArgs
- /// <summary>
- /// Event arguments used by the ListBoxDragDropManager.ProcessDrop event.
- /// </summary>
- /// <typeparam name="ItemType">The type of data object being dropped.</typeparam>
- public class ProcessDropEventArgs<ItemType> : EventArgs where ItemType : class
- {
- #region Data
- ObservableCollection<ItemType> itemsSource;
- ItemType dataItem;
- int oldIndex;
- int newIndex;
- DragDropEffects allowedEffects = DragDropEffects.None;
- DragDropEffects effects = DragDropEffects.None;
- #endregion // Data
- #region Constructor
- internal ProcessDropEventArgs(
- ObservableCollection<ItemType> 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
- /// <summary>
- /// The items source of the ListBox where the drop occurred.
- /// </summary>
- public ObservableCollection<ItemType> ItemsSource
- {
- get { return this.itemsSource; }
- }
- /// <summary>
- /// The data object which was dropped.
- /// </summary>
- public ItemType DataItem
- {
- get { return this.dataItem; }
- }
- /// <summary>
- /// The current index of the data item being dropped, in the ItemsSource collection.
- /// </summary>
- public int OldIndex
- {
- get { return this.oldIndex; }
- }
- /// <summary>
- /// The target index of the data item being dropped, in the ItemsSource collection.
- /// </summary>
- public int NewIndex
- {
- get { return this.newIndex; }
- }
- /// <summary>
- /// The drag drop effects allowed to be performed.
- /// </summary>
- public DragDropEffects AllowedEffects
- {
- get { return allowedEffects; }
- }
- /// <summary>
- /// The drag drop effect(s) performed on the dropped item.
- /// </summary>
- public DragDropEffects Effects
- {
- get { return effects; }
- set { effects = value; }
- }
- #endregion // Public Properties
- }
- #endregion // ProcessDropEventArgs
- }
|