Click here to Skip to main content
15,896,201 members
Articles / Desktop Programming / WPF

WPFSpark: 6 of n: FluidProgressBar

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
19 Jan 2012Ms-PL4 min read 45.3K   1.6K   20  
A Windows Phone style indeterminate ProgressBar in WPF.
#region File Header

// -------------------------------------------------------------------------------
// 
// This file is part of the WPFSpark project: http://wpfspark.codeplex.com/
//
// Author: Ratish Philip
// 
// WPFSpark v1.1
//
// -------------------------------------------------------------------------------

#endregion

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Media;

namespace WPFSpark
{
    /// <summary>
    /// Defines the Drag Behavior in the FluidWrapPanel using the Mouse
    /// </summary>
    public class FluidMouseDragBehavior : Behavior<UIElement>
    {
        #region Fields

        FluidWrapPanel parentFWPanel = null;
        ListBoxItem parentLBItem = null;

        #endregion

        #region Dependency Properties

        #region DragButton

        /// <summary>
        /// DragButton Dependency Property
        /// </summary>
        public static readonly DependencyProperty DragButtonProperty =
            DependencyProperty.Register("DragButton", typeof(MouseButton), typeof(FluidMouseDragBehavior),
                new FrameworkPropertyMetadata(MouseButton.Left));

        /// <summary>
        /// Gets or sets the DragButton property. This dependency property 
        /// indicates which Mouse button should participate in the drag interaction.
        /// </summary>
        public MouseButton DragButton
        {
            get { return (MouseButton)GetValue(DragButtonProperty); }
            set { SetValue(DragButtonProperty, value); }
        }

        #endregion

        #endregion

        #region Overrides

        /// <summary>
        /// 
        /// </summary>
        protected override void OnAttached()
        {
            // Subscribe to the Loaded event
            (this.AssociatedObject as FrameworkElement).Loaded += new RoutedEventHandler(OnAssociatedObjectLoaded);
        }

        void OnAssociatedObjectLoaded(object sender, RoutedEventArgs e)
        {
            // Get the parent FluidWrapPanel and check if the AssociatedObject is
            // hosted inside a ListBoxItem (this scenario will occur if the FluidWrapPanel
            // is the ItemsPanel for a ListBox).
            GetParentPanel();

            // Subscribe to the Mouse down/move/up events
            if (parentLBItem != null)
            {
                parentLBItem.PreviewMouseDown += new MouseButtonEventHandler(OnPreviewMouseDown);
                parentLBItem.PreviewMouseMove += new MouseEventHandler(OnPreviewMouseMove);
                parentLBItem.PreviewMouseUp += new MouseButtonEventHandler(OnPreviewMouseUp);
            }
            else
            {
                this.AssociatedObject.PreviewMouseDown += new MouseButtonEventHandler(OnPreviewMouseDown);
                this.AssociatedObject.PreviewMouseMove += new MouseEventHandler(OnPreviewMouseMove);
                this.AssociatedObject.PreviewMouseUp += new MouseButtonEventHandler(OnPreviewMouseUp);
            }
        }

        /// <summary>
        /// Get the parent FluidWrapPanel and check if the AssociatedObject is
        /// hosted inside a ListBoxItem (this scenario will occur if the FluidWrapPanel
        /// is the ItemsPanel for a ListBox).
        /// </summary>
        private void GetParentPanel()
        {
            FrameworkElement ancestor = this.AssociatedObject as FrameworkElement;

            while (ancestor != null)
            {
                if (ancestor is ListBoxItem)
                {
                    parentLBItem = ancestor as ListBoxItem;
                }

                if (ancestor is FluidWrapPanel)
                {
                    parentFWPanel = ancestor as FluidWrapPanel;
                    // No need to go further up
                    return;
                }

                // Find the visual ancestor of the current item
                ancestor = VisualTreeHelper.GetParent(ancestor) as FrameworkElement;
            }
        }

        protected override void OnDetaching()
        {
            (this.AssociatedObject as FrameworkElement).Loaded -= OnAssociatedObjectLoaded;
            if (parentLBItem != null)
            {
                parentLBItem.PreviewMouseDown -= OnPreviewMouseDown;
                parentLBItem.PreviewMouseMove -= OnPreviewMouseMove;
                parentLBItem.PreviewMouseUp -= OnPreviewMouseUp;
            }
            else
            {
                this.AssociatedObject.PreviewMouseDown -= OnPreviewMouseDown;
                this.AssociatedObject.PreviewMouseMove -= OnPreviewMouseMove;
                this.AssociatedObject.PreviewMouseUp -= OnPreviewMouseUp;
            }
        }

        #endregion

        #region Event Handlers

        void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == DragButton)
            {
                Point position = parentLBItem != null ? e.GetPosition(parentLBItem) : e.GetPosition(this.AssociatedObject);

                FrameworkElement fElem = this.AssociatedObject as FrameworkElement;
                if ((fElem != null) && (parentFWPanel != null))
                {
                    if (parentLBItem != null)
                        parentFWPanel.BeginFluidDrag(parentLBItem, position);
                    else
                        parentFWPanel.BeginFluidDrag(this.AssociatedObject, position);
                }
            }
        }

        void OnPreviewMouseMove(object sender, MouseEventArgs e)
        {
            bool isDragging = false;

            switch (DragButton)
            {
                case MouseButton.Left:
                    if (e.LeftButton == MouseButtonState.Pressed)
                    {
                        isDragging = true;
                    }
                    break;
                case MouseButton.Middle:
                    if (e.MiddleButton == MouseButtonState.Pressed)
                    {
                        isDragging = true;
                    }
                    break;
                case MouseButton.Right:
                    if (e.RightButton == MouseButtonState.Pressed)
                    {
                        isDragging = true;
                    }
                    break;
                case MouseButton.XButton1:
                    if (e.XButton1 == MouseButtonState.Pressed)
                    {
                        isDragging = true;
                    }
                    break;
                case MouseButton.XButton2:
                    if (e.XButton2 == MouseButtonState.Pressed)
                    {
                        isDragging = true;
                    }
                    break;
                default:
                    break;
            }

            if (isDragging)
            {
                Point position = parentLBItem != null ? e.GetPosition(parentLBItem) : e.GetPosition(this.AssociatedObject);

                FrameworkElement fElem = this.AssociatedObject as FrameworkElement;
                if ((fElem != null) && (parentFWPanel != null))
                {
                    Point positionInParent = e.GetPosition(parentFWPanel);
                    if (parentLBItem != null)
                        parentFWPanel.FluidDrag(parentLBItem, position, positionInParent);
                    else
                        parentFWPanel.FluidDrag(this.AssociatedObject, position, positionInParent);
                }
            }
        }

        void OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == DragButton)
            {
                Point position = parentLBItem != null ? e.GetPosition(parentLBItem) : e.GetPosition(this.AssociatedObject);

                FrameworkElement fElem = this.AssociatedObject as FrameworkElement;
                if ((fElem != null) && (parentFWPanel != null))
                {
                    Point positionInParent = e.GetPosition(parentFWPanel);
                    if (parentLBItem != null)
                        parentFWPanel.EndFluidDrag(parentLBItem, position, positionInParent);
                    else
                        parentFWPanel.EndFluidDrag(this.AssociatedObject, position, positionInParent);
                }
            }
        }

        #endregion
    }
}

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 Microsoft Public License (Ms-PL)


Written By
Software Developer
United States United States
An individual with more than a decade of experience in desktop computing and mobile app development primarily on the Microsoft platform. He loves programming in C#, WPF & XAML related technologies.
Current interests include web application development, developing rich user experiences across various platforms and exploring his creative side.

Ratish's personal blog: wpfspark.wordpress.com

Comments and Discussions