Click here to Skip to main content
12,889,969 members (45,957 online)
Click here to Skip to main content


192 bookmarked
Posted 27 Aug 2006

Dragging Elements in a Canvas

, 2 Sep 2006 CPOL
Discusses a class which provides automated dragging of elements in a WPF Canvas.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace DragCanvasDemo
	public partial class Window1 : Window
        #region Data

        /// <summary>
        /// Stores a reference to the UIElement which the Canvas's context menu currently targets.
        /// </summary>
        private UIElement elementForContextMenu;

        #endregion // Data

        #region Constructor

		public Window1()

            this.PreviewMouseRightButtonDown += Window1_PreviewMouseRightButtonDown;
            this.btnOnlyShowOffsetIndicators.Checked += btnOnlyShowOffsetIndicators_Checked;
            this.btnOnlyShowOffsetIndicators.Unchecked += btnOnlyShowOffsetIndicators_Unchecked;
            // Add the blocks which display their positions within the Canvas.
            foreach( string key in new string[] { 
												} )
                Button button = this.FindResource( key ) as Button;
				this.dragCanvas.Children.Add( button );


        #endregion // Constructor

        #region btnOnlyShowOffsetIndicators_Checked

        void btnOnlyShowOffsetIndicators_Checked( object sender, RoutedEventArgs e )
			foreach( UIElement child in this.dragCanvas.Children )
                child.Visibility =
                    child is Button && (child as Button).Content == null ?
                    Visibility.Visible :


        #endregion // btnOnlyShowOffsetIndicators_Checked

        #region btnOnlyShowOffsetIndicators_Unchecked

        void btnOnlyShowOffsetIndicators_Unchecked( object sender, RoutedEventArgs e )
			foreach( UIElement child in this.dragCanvas.Children )
                child.Visibility = Visibility.Visible;


        #endregion // btnOnlyShowOffsetIndicators_Unchecked        

        #region OnButtonClick

        private void OnButtonClick( object sender, RoutedEventArgs e )
            MessageBox.Show( "Thank you for clicking today, your clicks are important to us." );

        #endregion // OnButtonClick

		#region OnContextMenuOpened

		void OnContextMenuOpened( object sender, RoutedEventArgs e )
			if( this.elementForContextMenu != null )
				this.menuItemCanBeDragged.IsChecked = WPF.JoshSmith.Controls.DragCanvas.GetCanBeDragged( this.elementForContextMenu );

		#endregion // OnContextMenuOpened

		#region OnMenuItemClick

		/// <summary>
        /// Handles the Click event of both menu items in the context menu.
        /// </summary>
        void OnMenuItemClick( object sender, RoutedEventArgs e )
            if( this.elementForContextMenu == null )

			if( e.Source == this.menuItemBringToFront ||
				e.Source == this.menuItemSendToBack )
				bool bringToFront = e.Source == this.menuItemBringToFront;

				if( bringToFront )
					this.dragCanvas.BringToFront( this.elementForContextMenu );
					this.dragCanvas.SendToBack( this.elementForContextMenu );
				bool canBeDragged = WPF.JoshSmith.Controls.DragCanvas.GetCanBeDragged( this.elementForContextMenu );
				WPF.JoshSmith.Controls.DragCanvas.SetCanBeDragged( this.elementForContextMenu, !canBeDragged );
				(e.Source as MenuItem).IsChecked = !canBeDragged;

        #endregion // OnMenuItemClick

		#region ResetZOrder

		private void ResetZOrder()
			// Set the z-index of every visible child in the Canvas.
			int index = 0;
			for( int i = 0; i < this.dragCanvas.Children.Count; ++i )
				if( this.dragCanvas.Children[i].Visibility == Visibility.Visible )
					Canvas.SetZIndex( this.dragCanvas.Children[i], index++ );

		#endregion // ResetZOrder

		#region Window1_PreviewMouseRightButtonDown

		void Window1_PreviewMouseRightButtonDown( object sender, MouseButtonEventArgs e )
            // If the user right-clicks while dragging an element, assume that they want 
            // to manipulate the z-index of the element being dragged (even if it is  
            // behind another element at the time).
			if( this.dragCanvas.ElementBeingDragged != null )
				this.elementForContextMenu = this.dragCanvas.ElementBeingDragged;
                this.elementForContextMenu =
					this.dragCanvas.FindCanvasChild( e.Source as DependencyObject );

        #endregion // Window1_PreviewMouseRightButtonDown

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.


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


About the Author

Josh Smith
Software Developer (Senior) Cynergy Systems
United States United States
Josh creates software, for iOS and Windows.

He works at Cynergy Systems as a Senior Experience Developer.

Read his iOS Programming for .NET Developers[^] book to learn how to write iPhone and iPad apps by leveraging your existing .NET skills.

Use his Master WPF[^] app on your iPhone to sharpen your WPF skills on the go.

Check out his Advanced MVVM[^] book.

Visit his WPF blog[^] or stop by his iOS blog[^].

You may also be interested in...

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170424.1 | Last Updated 2 Sep 2006
Article Copyright 2006 by Josh Smith
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid