diff --git a/App.xaml b/App.xaml
index 5fc15ae..25aefa5 100644
--- a/App.xaml
+++ b/App.xaml
@@ -18,6 +18,53 @@
+
+
-
-
-
-
-
+
+
+
+
+
+
diff --git a/Controls/ExtendedListBox.cs b/Controls/ExtendedListBox.cs
new file mode 100644
index 0000000..6f4241e
--- /dev/null
+++ b/Controls/ExtendedListBox.cs
@@ -0,0 +1,152 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Controls;
+using System.Windows.Controls.Primitives;
+using System.Collections;
+
+namespace sbbs_client_wp7
+{
+ public class ExtendedListBox : ListBox
+ {
+ protected bool _isBouncy = false;
+ private bool alreadyHookedScrollEvents = false;
+
+ public ExtendedListBox()
+ {
+ this.Loaded += new RoutedEventHandler(ListBox_Loaded);
+ }
+
+ private void ListBox_Loaded(object sender, RoutedEventArgs e)
+ {
+ ScrollBar sb = null;
+ ScrollViewer sv = null;
+ if (alreadyHookedScrollEvents)
+ return;
+
+ alreadyHookedScrollEvents = true;
+ this.AddHandler(ExtendedListBox.ManipulationCompletedEvent, (EventHandler)LB_ManipulationCompleted, true);
+ sb = (ScrollBar)FindElementRecursive(this, typeof(ScrollBar));
+ sv = (ScrollViewer)FindElementRecursive(this, typeof(ScrollViewer));
+
+ if (sv != null)
+ {
+ // Visual States are always on the first child of the control template
+ FrameworkElement element = VisualTreeHelper.GetChild(sv, 0) as FrameworkElement;
+ if (element != null)
+ {
+ VisualStateGroup vgroup = FindVisualState(element, "VerticalCompression");
+ VisualStateGroup hgroup = FindVisualState(element, "HorizontalCompression");
+ if (vgroup != null)
+ vgroup.CurrentStateChanging += new EventHandler(vgroup_CurrentStateChanging);
+ if (hgroup != null)
+ hgroup.CurrentStateChanging += new EventHandler(hgroup_CurrentStateChanging);
+ }
+ }
+
+ }
+
+ public delegate void OnCompression(object sender, CompressionEventArgs e);
+ public event OnCompression Compression;
+
+ private void hgroup_CurrentStateChanging(object sender, VisualStateChangedEventArgs e)
+ {
+ if (e.NewState.Name == "CompressionLeft")
+ {
+ _isBouncy = true;
+ if (Compression != null)
+ Compression(this, new CompressionEventArgs(CompressionType.Left));
+ }
+
+ if (e.NewState.Name == "CompressionRight")
+ {
+ _isBouncy = true;
+ if (Compression != null)
+ Compression(this, new CompressionEventArgs(CompressionType.Right));
+ }
+ if (e.NewState.Name == "NoHorizontalCompression")
+ {
+ _isBouncy = false;
+ }
+ }
+
+ private void vgroup_CurrentStateChanging(object sender, VisualStateChangedEventArgs e)
+ {
+ if (e.NewState.Name == "CompressionTop")
+ {
+ _isBouncy = true;
+ if (Compression != null)
+ Compression(this, new CompressionEventArgs(CompressionType.Top));
+ }
+ if (e.NewState.Name == "CompressionBottom")
+ {
+ _isBouncy = true;
+ if (Compression != null)
+ Compression(this, new CompressionEventArgs(CompressionType.Bottom));
+ }
+ if (e.NewState.Name == "NoVerticalCompression")
+ _isBouncy = false;
+ }
+
+ private void LB_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
+ {
+ if (_isBouncy)
+ _isBouncy = false;
+ }
+
+ private UIElement FindElementRecursive(FrameworkElement parent, Type targetType)
+ {
+ int childCount = VisualTreeHelper.GetChildrenCount(parent);
+ UIElement returnElement = null;
+ if (childCount > 0)
+ {
+ for (int i = 0; i < childCount; i++)
+ {
+ Object element = VisualTreeHelper.GetChild(parent, i);
+ if (element.GetType() == targetType)
+ {
+ return element as UIElement;
+ }
+ else
+ {
+ returnElement = FindElementRecursive(VisualTreeHelper.GetChild(parent, i) as FrameworkElement, targetType);
+ }
+ }
+ }
+ return returnElement;
+ }
+
+ private VisualStateGroup FindVisualState(FrameworkElement element, string name)
+ {
+ if (element == null)
+ return null;
+
+ IList groups = VisualStateManager.GetVisualStateGroups(element);
+ foreach (VisualStateGroup group in groups)
+ if (group.Name == name)
+ return group;
+
+ return null;
+ }
+ }
+
+ public class CompressionEventArgs : EventArgs
+ {
+ public CompressionType Type { get; protected set; }
+
+ public CompressionEventArgs(CompressionType type)
+ {
+ Type = type;
+ }
+ }
+
+ public enum CompressionType { Top, Bottom, Left, Right };
+}
diff --git a/MainPage.xaml b/MainPage.xaml
index c76a397..1c88d36 100644
--- a/MainPage.xaml
+++ b/MainPage.xaml
@@ -104,8 +104,8 @@
-
-
+
+
diff --git a/sbbs-client-wp7.csproj b/sbbs-client-wp7.csproj
index 578736c..03de3ad 100644
--- a/sbbs-client-wp7.csproj
+++ b/sbbs-client-wp7.csproj
@@ -71,6 +71,7 @@
BoardSettingsPage.xaml
+