In the upcoming Silverlight 4 release, mousewheel support for controls will be implemented out of the box for the ScrollViewer, DataGrid, and ListBox controls.  However Silverlight 3 still requires you to roll your own mouse wheel support.  And Silverlight 4 does not offer a scrolling solution for Slider and TreeView.

The following MouseWheelProps class provides generic mousewheel support for all Silverlight controls that support the IScrollProvider interface (ScrollViewer, ListBox, DataGrid) or the IRangeValueProvider interface (Slider).  This class implements a single attached property called Enable that can be added directly to a control, or as a style for a control.

Step1: Add the following MouseWheelProps class to your Silverlight project:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace ClassLibrary
{
	public static class MouseWheelProps
	{
		// The Enabled attached property
		public static readonly DependencyProperty EnabledProperty = 
			DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(MouseWheelProps),
				new PropertyMetadata(false, OnEnabledPropertyChanged));

		public static bool GetEnabled(FrameworkElement element)
		{
			return (bool)element.GetValue(EnabledProperty);
		}

		public static void SetEnabled(FrameworkElement element, bool value)
		{
			element.SetValue(EnabledProperty, value);
		}

		private static void OnEnabledPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
		{
			UIElement element = sender as UIElement;
			if (element == null)
				return;
			bool enabled = (bool)e.NewValue;
			if (enabled)
				element.MouseWheel += OnMouseWheel;
			else
				element.MouseWheel -= OnMouseWheel;
		}

		private static void OnMouseWheel(object sender, MouseWheelEventArgs e)
		{
			if (e.Handled)
				return;

			UIElement element = sender as UIElement;
			if (element == null)
				return;

			AutomationPeer peer = FrameworkElementAutomationPeer.FromElement(element);
			if (peer == null)
				peer = FrameworkElementAutomationPeer.CreatePeerForElement(element);
			if (peer == null)
				return;

			// try to get the scroll provider or the range provider
			IScrollProvider m_ScrollProvider = peer.GetPattern(PatternInterface.Scroll) as IScrollProvider;
			IRangeValueProvider m_RangeValueProvider = null;
			if ((element is Control) && (element as Control).HasFocus())
				m_RangeValueProvider = peer.GetPattern(PatternInterface.RangeValue) as IRangeValueProvider;
			if (m_ScrollProvider == null && m_RangeValueProvider == null)
				return;

			// set scroll amount
			const double kMultiplier = 5.0; // x times the default
			const double kFactor = kMultiplier / (30 * 120);
			double delta = e.Delta;
			delta *= kFactor;
			int direction = Math.Sign(delta);

			bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0;
			bool controlKey = (Keyboard.Modifiers & ModifierKeys.Control) != 0;

			if (m_ScrollProvider != null)
			{
				e.Handled = true;
#if true
				if (m_ScrollProvider.VerticallyScrollable && !controlKey)
				{
					double percent = m_ScrollProvider.VerticalScrollPercent - (delta * m_ScrollProvider.VerticalViewSize);
					if (percent < 0) percent = 0;
					if (percent > 100) percent = 100;
					m_ScrollProvider.SetScrollPercent(m_ScrollProvider.HorizontalScrollPercent, percent);
				}
				else
				if (m_ScrollProvider.HorizontallyScrollable && controlKey)
				{
					double percent = m_ScrollProvider.HorizontalScrollPercent - (delta * m_ScrollProvider.HorizontalViewSize);
					if (percent < 0) percent = 0;
					if (percent > 100) percent = 100;
					m_ScrollProvider.SetScrollPercent(percent, m_ScrollProvider.VerticalScrollPercent);
				}
#else
				ScrollAmount scrollAmount = (direction < 0) ? ScrollAmount.SmallIncrement : ScrollAmount.SmallDecrement;
				if (m_ScrollProvider.VerticallyScrollable && !controlKey)
					m_ScrollProvider.Scroll(ScrollAmount.NoAmount, scrollAmount);
				else
				if (m_ScrollProvider.HorizontallyScrollable && controlKey)
					m_ScrollProvider.Scroll(scrollAmount, ScrollAmount.NoAmount);
#endif
			}

			if (m_RangeValueProvider != null)
			{
				e.Handled = true;
				double newValue = m_RangeValueProvider.Value + (direction < 0 ? -m_RangeValueProvider.LargeChange : m_RangeValueProvider.LargeChange);
				if (newValue >= m_RangeValueProvider.Minimum && newValue <= m_RangeValueProvider.Maximum)
					m_RangeValueProvider.SetValue(newValue);
			}
		}
	}

	internal static class ExtensionMethods
	{
		// Extension for UIElement
		internal static bool HasFocus(this UIElement element)
		{
			if (element == null)
				return false;

			DependencyObject focusedElement = FocusManager.GetFocusedElement() as DependencyObject;
			while (focusedElement != null)
			{
				if (element == focusedElement)
					return true;
				focusedElement = VisualTreeHelper.GetParent(focusedElement);
			}

			return false;
		}
	}
}

Step 2: Add the attached property c:MouseWheelProps.Enabled="True" either directly to a control, or as a Style that can be referenced by a control.

Added directly to a control:

<UserControl x:Class="SilverlightApplication.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:c="clr-namespace:ClassLibrary"
	xmlns:DataGrid="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
>
	<Grid>
		<DataGrid:DataGrid c:MouseWheelProps.Enabled="True" />
	</Grid>
</UserContro>

Added as a Style:

<UserControl x:Class="SilverlightApplication.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:c="clr-namespace:ClassLibrary"
	xmlns:DataGrid="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
>
	<Grid>
		<Grid.Resources>
			<Style x:Key="CommonDataGrid" TargetType="DataGrid:DataGrid">
				<Setter Property="c:MouseWheelProps.Enabled" Value="True" />
			</Style>
		</Grid.Resources>
		<DataGrid:DataGrid Style="{StaticResource CommonDataGrid}" />
	</Grid>
</UserContro>

 

That's all there is to it!