Click here to Skip to main content
15,891,674 members
Articles / Desktop Programming / WPF

WPF RichText Editor with Slider Formatting and a Font Style Dialog

Rate me:
Please Sign up or sign in to vote.
4.75/5 (5 votes)
5 Jul 2009CPOL9 min read 63.4K   4.1K   42  
WPF RichText Editor with custom Slider Control formatting and a Font Style Dialog box
// 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 WPF.JoshSmith.Adorners;
using WPF.JoshSmith.Controls.Utilities;

namespace WPF.JoshSmith.ServiceProviders.UI
{
	#region ListViewDragDropManager

	/// <summary>
	/// Manages the dragging and dropping of ListViewItems in a ListView.
	/// The ItemType type parameter indicates the type of the objects in
	/// the ListView's items source.  The ListView'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 ListView's items.</typeparam>
	public class ListViewDragDropManager<ItemType> where ItemType : class
	{
		#region Data

		bool canInitiateDrag;
		DragAdorner dragAdorner;
		double dragAdornerOpacity;
		int indexToSelect;
		bool isDragInProgress;
		ItemType itemUnderDragCursor;
		ListView listView;
		Point ptMouseDown;
		bool showDragAdorner;

		#endregion // Data

		#region Constructors

		/// <summary>
		/// Initializes a new instance of ListViewDragManager.
		/// </summary>
		public ListViewDragDropManager()
		{
			this.canInitiateDrag = false;
			this.dragAdornerOpacity = 0.7;
			this.indexToSelect = -1;
			this.showDragAdorner = true;
		}

		/// <summary>
		/// Initializes a new instance of ListViewDragManager.
		/// </summary>
		/// <param name="listView"></param>
		public ListViewDragDropManager( ListView listView )
			: this()
		{
			this.ListView = listView;
		}

		/// <summary>
		/// Initializes a new instance of ListViewDragManager.
		/// </summary>
		/// <param name="listView"></param>
		/// <param name="dragAdornerOpacity"></param>
		public ListViewDragDropManager( ListView listView, double dragAdornerOpacity )
			: this( listView )
		{
			this.DragAdornerOpacity = dragAdornerOpacity;
		}

		/// <summary>
		/// Initializes a new instance of ListViewDragManager.
		/// </summary>
		/// <param name="listView"></param>
		/// <param name="showDragAdorner"></param>
		public ListViewDragDropManager( ListView listView, bool showDragAdorner )
			: this( listView )
		{
			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 ListView

		/// <summary>
		/// Gets/sets the ListView whose dragging is managed.  This property
		/// can be set to null, to prevent drag management from occuring.  If
		/// the ListView's AllowDrop property is false, it will be set to true.
		/// </summary>
		public ListView ListView
		{
			get { return listView; }
			set
			{
				if( this.IsDragInProgress )
					throw new InvalidOperationException( "Cannot set the ListView property during a drag operation." );

				if( this.listView != null )
				{
					#region Unhook Events

					this.listView.PreviewMouseLeftButtonDown -= listView_PreviewMouseLeftButtonDown;
					this.listView.PreviewMouseMove -= listView_PreviewMouseMove;
					this.listView.DragOver -= listView_DragOver;
					this.listView.DragLeave -= listView_DragLeave;
					this.listView.DragEnter -= listView_DragEnter;
					this.listView.Drop -= listView_Drop;

					#endregion // Unhook Events
				}

				this.listView = value;

				if( this.listView != null )
				{
					if( !this.listView.AllowDrop )
						this.listView.AllowDrop = true;

					#region Hook Events

					this.listView.PreviewMouseLeftButtonDown += listView_PreviewMouseLeftButtonDown;
					this.listView.PreviewMouseMove += listView_PreviewMouseMove;
					this.listView.DragOver += listView_DragOver;
					this.listView.DragLeave += listView_DragLeave;
					this.listView.DragEnter += listView_DragEnter;
					this.listView.Drop += listView_Drop;

					#endregion // Hook Events
				}
			}
		}

			#endregion // ListView

			#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 ListViewItem 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 listView_PreviewMouseLeftButtonDown

		void listView_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 ListViewItem the user clicked on for later.
				this.ptMouseDown = MouseUtilities.GetMousePosition( this.listView );
				this.indexToSelect = index;
			}
			else
			{
				this.ptMouseDown = new Point( -10000, -10000 );
				this.indexToSelect = -1;
			}
		}

			#endregion // listView_PreviewMouseLeftButtonDown

			#region listView_PreviewMouseMove

		void listView_PreviewMouseMove( object sender, MouseEventArgs e )
		{
			if( !this.CanStartDragOperation )
				return;

			// Select the item the user clicked on.
			if( this.listView.SelectedIndex != this.indexToSelect )
				this.listView.SelectedIndex = this.indexToSelect;

			// If the item at the selected index is null, there's nothing
			// we can do, so just return;
			if( this.listView.SelectedItem == null )
				return;

			ListViewItem itemToDrag = this.GetListViewItem( this.listView.SelectedIndex );
			if( itemToDrag == null )
				return;

			AdornerLayer adornerLayer = this.ShowDragAdornerResolved ? this.InitializeAdornerLayer( itemToDrag ) : null;

			this.InitializeDragOperation( itemToDrag );
			this.PerformDragOperation();
			this.FinishDragOperation( itemToDrag, adornerLayer );
		}

			#endregion // listView_PreviewMouseMove

			#region listView_DragOver

		void listView_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.ListView.Items[index] as ItemType;
		}

			#endregion // listView_DragOver

			#region listView_DragLeave

		void listView_DragLeave( object sender, DragEventArgs e )
		{
			if( !this.IsMouseOver( this.listView ) )
			{
				if( this.ItemUnderDragCursor != null )
					this.ItemUnderDragCursor = null;

				if( this.dragAdorner != null )
					this.dragAdorner.Visibility = Visibility.Collapsed;
			}
		}

			#endregion // listView_DragLeave

			#region listView_DragEnter

		void listView_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 // listView_DragEnter

			#region listView_Drop

		void listView_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.listView.ItemsSource as ObservableCollection<ItemType>;
			if( itemsSource == null )
				throw new Exception(
					"A ListView managed by ListViewDragManager 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 ListView 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 ListView 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 ListView into
				// our ListView, 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 );
				else
					itemsSource.Insert( newIndex, data );

				// Set the Effects property so that the call to DoDragDrop will return 'Move'.
				e.Effects = DragDropEffects.Move;
			}
		}

			#endregion // listView_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( ListViewItem draggedItem, AdornerLayer adornerLayer )
		{
			// Let the ListViewItem know that it is not being dragged anymore.
			ListViewItemDragState.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 GetListViewItem

		ListViewItem GetListViewItem( int index )
		{
			if ( this.listView.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated )
				return null;
			return this.listView.ItemContainerGenerator.ContainerFromIndex( index ) as ListViewItem;
		}

		ListViewItem GetListViewItem( ItemType dataItem )
		{
			if( this.listView.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated )
				return null;

			return this.listView.ItemContainerGenerator.ContainerFromItem( dataItem ) as ListViewItem;
		}

			#endregion // GetListViewItem

			#region HasCursorLeftDragThreshold

		bool HasCursorLeftDragThreshold
		{
			get
			{
				if( this.indexToSelect < 0 )
					return false;

				ListViewItem item = this.GetListViewItem( this.indexToSelect );
				Rect bounds = VisualTreeHelper.GetDescendantBounds( item );
				Point ptInItem = this.listView.TranslatePoint( this.ptMouseDown, item );

				// In case the cursor is at the very top or bottom of the ListViewItem
				// 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 ptInListView = MouseUtilities.GetMousePosition( this.listView );
				return !rect.Contains( ptInListView );
			}
		}

			#endregion // HasCursorLeftDragThreshold

			#region IndexUnderDragCursor

		/// <summary>
		/// Returns the index of the ListViewItem 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.listView.Items.Count; ++i )
				{
					ListViewItem item = this.GetListViewItem( i );
                    if (item == null)
                    { }
                    else
					if( this.IsMouseOver( item ) )
					{
						index = i;
						break;
					}
				}
				return index;
			}
		}

			#endregion // IndexUnderDragCursor

			#region InitializeAdornerLayer

		AdornerLayer InitializeAdornerLayer( ListViewItem itemToDrag )
		{
			// Create a brush which will paint the ListViewItem 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.listView, itemToDrag.RenderSize, brush );
			
			// Set the drag adorner's opacity.		
			this.dragAdorner.Opacity = this.DragAdornerOpacity;

			AdornerLayer layer = AdornerLayer.GetAdornerLayer( this.listView );
			layer.Add( dragAdorner );

			// Save the location of the cursor when the left mouse button was pressed.
			this.ptMouseDown = MouseUtilities.GetMousePosition( this.listView );

			return layer;
		}

			#endregion // InitializeAdornerLayer

			#region InitializeDragOperation

		void InitializeDragOperation( ListViewItem itemToDrag )
		{
			// Set some flags used during the drag operation.
			this.IsDragInProgress = true;
			this.canInitiateDrag = false;

			// Let the ListViewItem know that it is being dragged.
			ListViewItemDragState.SetIsBeingDragged( itemToDrag, true );
		}

			#endregion // InitializeDragOperation

			#region IsMouseOver

		bool IsMouseOver( Visual target )
		{
			// We need to use MouseUtilities 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 = MouseUtilities.GetMousePosition( target );
			return bounds.Contains( mousePos );
		}

			#endregion // IsMouseOver

			#region IsMouseOverScrollbar

		/// <summary>
		/// Returns true if the mouse cursor is over a scrollbar in the ListView.
		/// </summary>
		bool IsMouseOverScrollbar
		{
			get
			{
				Point ptMouse = MouseUtilities.GetMousePosition( this.listView );
				HitTestResult res = VisualTreeHelper.HitTest( this.listView, 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 )
					{
						ListViewItem listViewItem = this.GetListViewItem( this.itemUnderDragCursor );
						if( listViewItem != null )
							ListViewItemDragState.SetIsUnderDragCursor( listViewItem, i == 1 );
					}
				}
			}
		}

			#endregion // ItemUnderDragCursor

			#region PerformDragOperation

		void PerformDragOperation()
		{
			ItemType selectedItem = this.listView.SelectedItem as ItemType;
			DragDropEffects allowedEffects = DragDropEffects.Move | DragDropEffects.Move | DragDropEffects.Link;
			if( DragDrop.DoDragDrop( this.listView, selectedItem, allowedEffects ) != DragDropEffects.None )
			{
				// The item was dropped into a new location,
				// so make it the new selected item.
				this.listView.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 = MouseUtilities.GetMousePosition( this.ListView );

				double left = ptCursor.X - this.ptMouseDown.X;

				// 4/13/2007 - Made the top offset relative to the item being dragged.
				ListViewItem itemBeingDragged = this.GetListViewItem( this.indexToSelect );
				Point itemLoc = itemBeingDragged.TranslatePoint( new Point( 0, 0 ), this.ListView );
				double top = itemLoc.Y + ptCursor.Y - this.ptMouseDown.Y;

				this.dragAdorner.SetOffsets( left, top );
			}
		}

			#endregion // UpdateDragAdornerLocation

		#endregion // Private Helpers
	}

	#endregion // ListViewDragDropManager

	#region ListViewItemDragState

	/// <summary>
	/// Exposes attached properties used in conjunction with the ListViewDragDropManager class.
	/// Those properties can be used to allow triggers to modify the appearance of ListViewItems
	/// in a ListView during a drag-drop operation.
	/// </summary>
	public static class ListViewItemDragState
	{
		#region IsBeingDragged

		/// <summary>
		/// Identifies the ListViewItemDragState's IsBeingDragged attached property.  
		/// This field is read-only.
		/// </summary>
		public static readonly DependencyProperty IsBeingDraggedProperty =
			DependencyProperty.RegisterAttached(
				"IsBeingDragged",
				typeof( bool ),
				typeof( ListViewItemDragState ),
				new UIPropertyMetadata( false ) );

		/// <summary>
		/// Returns true if the specified ListViewItem is being dragged, else false.
		/// </summary>
		/// <param name="item">The ListViewItem to check.</param>
		public static bool GetIsBeingDragged( ListViewItem item )
		{
			return (bool)item.GetValue( IsBeingDraggedProperty );
		}

		/// <summary>
		/// Sets the IsBeingDragged attached property for the specified ListViewItem.
		/// </summary>
		/// <param name="item">The ListViewItem to set the property on.</param>
		/// <param name="value">Pass true if the element is being dragged, else false.</param>
		internal static void SetIsBeingDragged( ListViewItem item, bool value )
		{
			item.SetValue( IsBeingDraggedProperty, value );
		}

		#endregion // IsBeingDragged

		#region IsUnderDragCursor

		/// <summary>
		/// Identifies the ListViewItemDragState's IsUnderDragCursor attached property.  
		/// This field is read-only.
		/// </summary>
		public static readonly DependencyProperty IsUnderDragCursorProperty =
			DependencyProperty.RegisterAttached(
				"IsUnderDragCursor",
				typeof( bool ),
				typeof( ListViewItemDragState ),
				new UIPropertyMetadata( false ) );

		/// <summary>
		/// Returns true if the specified ListViewItem is currently underneath the cursor 
		/// during a drag-drop operation, else false.
		/// </summary>
		/// <param name="item">The ListViewItem to check.</param>
		public static bool GetIsUnderDragCursor( ListViewItem item )
		{
			return (bool)item.GetValue( IsUnderDragCursorProperty );
		}

		/// <summary>
		/// Sets the IsUnderDragCursor attached property for the specified ListViewItem.
		/// </summary>
		/// <param name="item">The ListViewItem 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( ListViewItem item, bool value )
		{
			item.SetValue( IsUnderDragCursorProperty, value );
		}

		#endregion // IsUnderDragCursor
	}

	#endregion // ListViewItemDragState

	#region ProcessDropEventArgs

	/// <summary>
	/// Event arguments used by the ListViewDragDropManager.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 ListView 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
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions