Adding mouse wheel support to ScrollViewer

As we know there is no MouseWheel support to scroll as of Beta 2 and there are many ways out there to do the same

here is another way to do the same

Lets start with a couple of ListBoxes one which we add MouseWheel support and other not

  <Canvas>
        <ListBox x:Name=”list1″
                 Width=”200″
                 Height=”200″
                 local:Page.AddMouseWheelSupport=”true”></ListBox>     
        <ListBox x:Name=”list3″
                 Margin=”250, 0,0,0″
                 Width=”200″
                 Height=”200″></ListBox>
    </Canvas>

you will see a datagrid(in the samplecode). I thought it uses ScrollViewer. looks like it doesn’t so this technique wont work with that. This should work with any control that has ScrollViewer, did not try for any other Control.

Created a Attached property like this

public static bool GetAddMouseWheelSupport(DependencyObject obj)
        {
            return (bool)obj.GetValue(AddMouseWheelSupportProperty);
        }

        public static void SetAddMouseWheelSupport(DependencyObject obj, bool value)
        {
            obj.SetValue(AddMouseWheelSupportProperty, value);
        }

        // Using a DependencyProperty as the backing store for AddMouseWheelSupport.  This enables animation, styling, binding, etc…
        public static readonly DependencyProperty AddMouseWheelSupportProperty =
            DependencyProperty.RegisterAttached(“AddMouseWheelSupport”, typeof(bool), typeof(Page), new PropertyMetadata(ValueChanged));

        static void ValueChanged(DependencyObject obj,DependencyPropertyChangedEventArgs args)
        {
          
        }

you can see that we added the attached property to the 1st listbox

local:Page.AddMouseWheelSupport=”true”

we did not add this attribute to the 2nd listbox, so one of them will have the support and other wont

The main logic is in the function OnMouseWheel.1st part of the code is copied from Mike snow’s Blog, along with code for hooking up the events

 HtmlPage.Window.AttachEvent(“DOMMouseScroll”, OnMouseWheel);
 HtmlPage.Window.AttachEvent(“onmousewheel”, OnMouseWheel);
 HtmlPage.Document.AttachEvent(“onmousewheel”, OnMouseWheel);

 private void OnMouseWheel(object sender, HtmlEventArgs args){   
            double mouseDelta = 0;   
            ScriptObject e = args.EventObject;     // Mozilla and Safari   
            if (e.GetProperty(“detail”) != null)     {       
                mouseDelta = ((double)e.GetProperty(“detail”));   
            }   
            // IE and Opera   
            else if (e.GetProperty(“wheelDelta”) != null)        
                mouseDelta = ((double)e.GetProperty(“wheelDelta”));    

            List<UIElement> elements = this.HitTest(new Point(args.ClientX, args.ClientY)) as List<UIElement>;
            Control control = null;
            for (int i = 0; i < elements.Count-1; i++)
            {

                if (elements[i].GetType() == typeof(ListBox))
                {
                    control = elements[i] as Control;
                    break;
                }
             
            }

            if (control == null)
                return;
           
            mouseDelta = Math.Sign(mouseDelta);
            if ((bool)control.GetValue(AddMouseWheelSupportProperty))
            {
                ScrollViewer sv = GetChild<ScrollViewer>(control);
                if (sv == null)
                    return;
                if (mouseDelta == 1)
                    sv.ScrollToVerticalOffset(sv.VerticalOffset – 30);
                else
                    sv.ScrollToVerticalOffset(sv.VerticalOffset + 30);
            }
        }

What we are doing is doing a HitTest with ClientX and ClientY positions  to get a list of elements and checking is there is a listbox in the list of elements returned.
If we find one and the AttachedProperty ‘AddMouseWheelSupportProperty’ is set we get the ScrollViewer from the VisualTree and change the verticaloffset by some amount (30 in the sample)

you can download the code here

Advertisements

5 thoughts on “Adding mouse wheel support to ScrollViewer

  1. With Silverlight 2.0, HitTest is moved to VisualTreeHelper.FindTestElementsInHostCoordinates. Replace

    List elements = this.HitTest(new Point(args.ClientX, args.ClientY)) as List

    with

    List elements = VisualTreeHelper.FindElementsInHostCoordinates(new Point(args.ClientX, args.ClientY),this) as List;

  2. to make scrollviewer to scroll by mousewheel,
    in Silverlight 3 this problem got fixed as follows:
    1- Have the DLL Reference of System.Windows.Controls.Toolkit
    2- put the statemaent: SCRVIEW.SetIsMouseWheelScrollingEnabled(true); after
    intiliaizeComponent(); // SCRVIEW is the name of Scrollviewer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s