Click here to Skip to main content
11,646,635 members (73,314 online)
Click here to Skip to main content
Add your own
alternative version

Wrap Panel Virtualization

, 2 Jan 2012 CPOL 22.4K 3.5K 35
WrapPanel doesn't support virtualization. But we can improve the performance by simulating virtualization.
mediaassistant_bin-noexe.zip
MediaAssistant_bin.zip
MediaAssistant_src
DokanNet.dll
Id3Lib.dll
Media Assistant.exe
Media Assistant.exe.manifest
MediaAssistant.DAL.dll
MediaFS.dll
MefBasic.dll
Microsoft.Practices.Composite.dll
Microsoft.Practices.Composite.MefExtensions.dll
Microsoft.Practices.Composite.Presentation.dll
Microsoft.Practices.ServiceLocation.dll
Mp3Lib.dll
Newtonsoft.Json.Net35.dll
SharpZipLib.dll
Tags.dll
mediaassistant_src-noexe.zip
MediaAssistant_src.zip
DokanNet
Properties
Lib
CommonServiceLocation
Desktop
Microsoft.Practices.ServiceLocation.dll
CompositeApplicationLibrary
Desktop
Microsoft.Practices.Composite.dll
Microsoft.Practices.Composite.MefExtensions.dll
Microsoft.Practices.Composite.Presentation.dll
Dokan
dokan.lib
Moq
Desktop
Moq.dll
Mp3Lib
Id3Lib.dll
Mp3Lib.dll
SharpZipLib.dll
Newtonsoft
Newtonsoft.Json.Net35.dll
NUnit
nunit.framework.dll
MediaAssistant
MediaAssistant.csproj.user
MediaAssistant.ico
MusicAssistant_TemporaryKey.pfx
Constants
Controls
About
AddMovie
AlternativeLocation
BottomPanel
Dialog
LeftPanel
Library
MessageBox
MovieDetail
MovieList
MovieMiddlePanel
MovieResult
MovieSearchControl
MovieThumbnails
MusicList
MusicMiddlePanel
MusicSearchControl
PlayerControl
PlayingMusicInfo
PlaylistSelector
ProfileSelector
SendFeedback
SmartDJPreferance
SplashScreen
SplashPage.png
StatusMessageBar
TagEditor
TopPanel
WaitScreen
Converters
Data
EventArguments
HeaderImages
Close_act.png
Close_inact.png
Close_pr.png
Maximize_act.png
Maximize_inact.png
Maximize_pr.png
Minimize_act.png
Minimize_inact.png
Minimize_pr.png
Helper
Images
AcceptFolder.png
Actor.png
ActorLibrary.png
AddFolder.png
Album.png
Artist.png
Close.png
Composer.png
Default.png
DeleteFolder.png
Director.png
DrivesMovies.png
eye16.png
FailedToPlayMusic.png
Genre.png
IMDB.png
Library.png
ListView.png
Logo.png
Maximize.png
Menu.png
Mount.png
MovieBackground.jpg
MovieBackground.png
MovieFolder.png
MovieGenre.png
MovieLibrary.png
MoviePoster.png
Music.png
MusicAssistant.png
MusicLibrary.png
Mute.png
New.png
NewMovies.png
NoDJ.png
NonPlayingMusic.png
NormalShuffle.png
NoShuffle.png
NowPlayingMusic.png
PlayingMusic.png
playlist.png
PlayMovie.png
ProcessDone.png
ProcessFailed.png
Processing.png
Rated.png
Recent.png
RecommendedMovie.png
Restore.png
Runtime.png
SmartShuffle.png
Song.png
Star.png
Swap.png
ThumbnailView.png
Tools.png
TreeCollapse.png
TreeExpand.png
Unread.png
Volume.png
WatchList.png
WishList.png
Writer.png
Year.png
Management
MusicDJ
Properties
Settings.settings
Resources
MediaAssistant.DAL
MediaAssistant.sdf
MediaAssistantModels.edmx
Constants
DBUpdateScript
Helper
Properties
Settings.settings
DataSources
MusicAssistantEntities.datasource
TasteKidEntities.datasource
Virtualization
MediaAssistant.Setup
MusicAssistant.Setup.vdproj
MediaFS
DokanInstall_0.6.0.exe
Properties
MefBasic
Behaviors
Commans
Controls
Converters
Data
Extensions
Helper
Properties
Settings.settings
Themes
Threading
UserControls
Properties
TagClass
ASF Classes
Frames Classes
ID3
Properties
Text Files
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Animation;

namespace MefBasic.UserControls
{
    public partial class CollapsibleContainer
    {
        private const string LeftIcon = "LeftIcon";
        private const string RightIcon = "RightIcon";
        private const string UpIcon = "UpIcon";
        private const string DownIcon = "DownIcon";
        private const double Delay = 0.25;

        public static readonly DependencyProperty IsExpandedProperty =
            DependencyProperty.Register("IsExpanded", typeof (bool), typeof (CollapsibleContainer),
                                        new UIPropertyMetadata(true, OnPropertyChanged));

        private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = (CollapsibleContainer) d;
            control.DoPropertyChanged(e);
        }

        private void DoPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            switch (e.Property.Name)
            {
                case "IsExpanded":
                    RefreshView();
                    break;
                case "Child":
                    childContentControl.Content = Child;
                    break;
                case "Direction":
                    HideAllBorder();
                    RefreshView();
                    break;
            }
        }

        private void HideAllBorder()
        {
            btnLeft.Visibility = Visibility.Collapsed;
            btnTop.Visibility = Visibility.Collapsed;
            btnRight.Visibility = Visibility.Collapsed;
            btnBottom.Visibility = Visibility.Collapsed;
        }

        public static readonly DependencyProperty ChildProperty =
            DependencyProperty.Register("Child", typeof (object), typeof (CollapsibleContainer),
                                        new UIPropertyMetadata(null,OnPropertyChanged));

        private double _delay;
        private Point _initialMousePosition;
        private bool _isDragging;

        private bool _isLoaded;

        public CollapsibleContainer()
        {
            InitializeComponent();
            InitializeMyComponent();
            imgLeft.Content = FindResource(LeftIcon);
            imgTop.Content = FindResource(UpIcon);
            imgRight.Content = FindResource(RightIcon);
            imgBottom.Content = FindResource(DownIcon);
        }

        public bool IsAnimationOn { set; get; }
        public bool CanCollapse { get; set; }

        public bool IsExpanded
        {
            get { return (bool) GetValue(IsExpandedProperty); }
            set { SetValue(IsExpandedProperty, value); }
        }

        public object Child
        {
            get { return GetValue(ChildProperty); }
            set { SetValue(ChildProperty, value); }
        }

        public event EventHandler AnimationCompleted;


        private void InitializeMyComponent()
        {
            IsAnimationOn = true;
            SubscribeMouseDown();
            contentHolder.Loaded += HandleLoaded;
            contentHolder.SizeChanged += HandleContentHolderSizeChanged;
            _delay = Delay;
        }

        private void HandleContentHolderSizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (ContentSize==0)
                ContentSize = Math.Max(ContentSize, GetActualSize());
        }

        private void SubscribeMouseDown()
        {
            imgLeft.PreviewMouseDown += BtnShowHideMouseUp;
            imgTop.PreviewMouseDown += BtnShowHideMouseUp;
            imgRight.PreviewMouseDown += BtnShowHideMouseUp;
            imgBottom.PreviewMouseDown += BtnShowHideMouseUp;
        }

        private double GetActualSize()
        {
            switch (Direction)
            {
                case Direction.LeftToRight:
                case Direction.RightToLeft:
                    return contentHolder.ActualWidth;
                case Direction.TopToBottom:
                case Direction.BottomToTop:
                    return contentHolder.ActualHeight;
            }
            return 0;
        }

        private void HandleLoaded(object sender, RoutedEventArgs e)
        {
            if (_isLoaded) return;
            _isLoaded = true;
            ContentSize = GetActualSize();
            UpdateImage();
        }

        private void OnAnimationCompleted()
        {
            if (AnimationCompleted != null)
            {
                AnimationCompleted(this, new EventArgs());
            }
        }


        private void BtnShowHideMouseUp(object sender, MouseButtonEventArgs e)
        {
            IsExpanded = !IsExpanded;
            RefreshView();
            e.Handled = true;
        }


        public ICommand ExpandCollapseChangedCommand
        {
            get { return (ICommand)GetValue(ExpandCollapseChangedCommandProperty); }
            set { SetValue(ExpandCollapseChangedCommandProperty, value); }
        }

        public static readonly DependencyProperty ExpandCollapseChangedCommandProperty =
            DependencyProperty.Register("ExpandCollapseChangedCommand", typeof(ICommand), typeof(CollapsibleContainer), new UIPropertyMetadata(null));



        public object ExpandCollapseChangedCommandParameter
        {
            get { return (object)GetValue(ExpandCollapseChangedCommandParameterProperty); }
            set { SetValue(ExpandCollapseChangedCommandParameterProperty, value); }
        }

        public static readonly DependencyProperty ExpandCollapseChangedCommandParameterProperty =
            DependencyProperty.Register("ExpandCollapseChangedCommandParameter", typeof(object), typeof(CollapsibleContainer), new UIPropertyMetadata(null));


        private void RefreshView()
        {
            UpdateImage();
            if (IsExpanded)
                Expand();
            else
                Collapse();
        }


        public void SetSizable(bool isSizable)
        {
            if (isSizable)
            {
                SubscribeEventsForSizable(btnLeft);
                SubscribeEventsForSizable(btnTop);
                SubscribeEventsForSizable(btnRight);
                SubscribeEventsForSizable(btnBottom);
            }
            else
            {
                UnsubscribeEventsForSizable(btnLeft);
                UnsubscribeEventsForSizable(btnTop);
                UnsubscribeEventsForSizable(btnRight);
                UnsubscribeEventsForSizable(btnBottom);
            }
        }

        private void UnsubscribeEventsForSizable(Border border)
        {
            border.MouseMove -= OnBorderMouseMove;
            border.MouseLeftButtonDown -= OnBorderMouseLeftButtonDown;
            border.MouseLeftButtonUp -= OnBorderMouseLeftButtonUp;
            border.Cursor = Cursors.Arrow;
        }

        private void SubscribeEventsForSizable(Border border)
        {
            border.MouseMove += OnBorderMouseMove;
            border.MouseLeftButtonDown += OnBorderMouseLeftButtonDown;
            border.MouseLeftButtonUp += OnBorderMouseLeftButtonUp;
            border.Cursor = Cursors.SizeWE;
        }


        public void Collapse()
        {
            if (!_isLoaded) return;
            if (IsAnimationOn)
            {
                Animate(ContentSize, 0);
            }
            else
            {
                contentHolder.Visibility = Visibility.Collapsed;
            }
        }

        public void Expand()
        {
            if (!_isLoaded) return;
            if (IsAnimationOn)
            {
                Animate(0, ContentSize);
            }
            else
            {
                contentHolder.Visibility = Visibility.Visible;
            }
        }



        public Direction Direction
        {
            get { return (Direction)GetValue(DirectionProperty); }
            set { SetValue(DirectionProperty, value); }
        }

        public double ContentSize { get; set; }

        public static readonly DependencyProperty DirectionProperty =
            DependencyProperty.Register("Direction", typeof(Direction), typeof(CollapsibleContainer), new UIPropertyMetadata(Direction.LeftToRight,OnPropertyChanged));

        public void Animate(double from, double to)
        {
            var dbAnimation = new DoubleAnimation();
            dbAnimation.Completed += DoubleAnimationCompleted;
            dbAnimation.From = from;
            dbAnimation.To = to;
            dbAnimation.Duration = new Duration(TimeSpan.FromSeconds(_delay));
            switch (Direction)
            {
                case Direction.LeftToRight:
                case Direction.RightToLeft:
                    contentContainer.BeginAnimation(WidthProperty, dbAnimation);    
                    break;
                case Direction.TopToBottom:
                case Direction.BottomToTop:
                    contentContainer.BeginAnimation(HeightProperty, dbAnimation);
                    break;
            }
            
        }

        private void DoubleAnimationCompleted(object sender, EventArgs e)
        {
            UpdateImage();
            _delay = Delay;
            if (!_isDragging)
            {
                OnAnimationCompleted();
            }
            if (ExpandCollapseChangedCommand != null)
            {
                ExpandCollapseChangedCommand.Execute(ExpandCollapseChangedCommandParameter);
            }
        }


        private void UpdateImage()
        {
            switch (Direction)
            {
                case Direction.LeftToRight:
                    btnLeft.Visibility = Visibility.Visible;
                    imgLeft.Content = FindResource(IsExpanded ? RightIcon : LeftIcon);
                    break;
                case Direction.RightToLeft:
                    btnRight.Visibility = Visibility.Visible;
                    imgRight.Content = FindResource(IsExpanded ? LeftIcon : RightIcon);
                    break;
                case Direction.TopToBottom:
                    btnTop.Visibility = Visibility.Visible;
                    imgTop.Content = FindResource(IsExpanded ? DownIcon : UpIcon);
                    break;
                case Direction.BottomToTop:
                    btnBottom.Visibility = Visibility.Visible;
                    imgBottom.Content = FindResource(IsExpanded ? UpIcon : DownIcon);
                    break;
            }
        }


        private void OnBorderMouseMove(object sender, MouseEventArgs e)
        {
            if (!IsExpanded) return;
            if (e.LeftButton != MouseButtonState.Pressed) return;

            var currentPosition = e.GetPosition(this);
            var deltaX = currentPosition.X - _initialMousePosition.X;

            var absDelta = Math.Abs(deltaX);
            if (absDelta < SystemParameters.MinimumHorizontalDragDistance) return;
            if (!_isDragging)
            {
                _isDragging = true;
            }
            _initialMousePosition = currentPosition;
            var currentWidth = contentHolder.ActualWidth;
            var newWidth = contentHolder.ActualWidth;
            if (IsWidthIncreasing(deltaX))
            {
                if ((newWidth + absDelta) <= (Application.Current.MainWindow.ActualWidth/2))
                    newWidth += absDelta;
            }
            else
            {
                if (newWidth - absDelta >= contentHolder.MinWidth)
                    newWidth -= absDelta;
            }
            _delay = 0;
            Animate(currentWidth, newWidth);
        }

        private bool IsWidthIncreasing(double deltaX)
        {
            if (Direction == Direction.RightToLeft)
            {
                return deltaX > 0;
            }
            return deltaX < 0;
        }

        private void OnBorderMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var border = (Border) sender;
            Mouse.Capture(border);
            _initialMousePosition = e.GetPosition(this);
        }

        private void OnBorderMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _isDragging = false;
            Mouse.Capture(null);
        }
    }
}

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)

Share

About the Author

H. S. Masud
Software Developer (Senior) KAZ Software Limited
Bangladesh Bangladesh
No Biography provided

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150731.1 | Last Updated 2 Jan 2012
Article Copyright 2012 by H. S. Masud
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid