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