MouseWheel Behavior for Silverlight

A demonstration of the MouseWheel behavior to add mouse wheel-based scrolling in Silverlight applications, effortlessly, using Silverlight.FX and behaviors...

Earlier today I saw a comment about adding mouse wheel support for Silverlight apps and controls in the form of a behavior. I thought I'd put together a sample of a using the MouseWheelScroll behavior that already exists in Silverlight.FX. Its really quite straightforward... just attach one to any ScrollViewer control (actually any control that provides the scrolling automation peer functionality), or to some control that contains one in its control template (for example, a TextBox).

On the right is a screenshot of the live sample (note that this does work with Silverlight 2 as well). You can download the sample, and you can also download Silverlight.FX from its project page along with associated samples to see what else is in the works.

Here are the relevant bits of XAML:

<UserControl ... 
  xmlns:fxui="clr-namespace:SilverlightFX.UserInterface;assembly=SilverlightFX">
  <Grid> 

    <ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Disabled">
      <fxui:Interaction.Behaviors>
        <fxui:MouseWheelScroll />
      </fxui:Interaction.Behaviors>
      <Image Source="/SL3Poster.png" Width="450" />
    </ScrollViewer> 

    <TextBox
      VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Disabled"
      TextWrapping="Wrap">
      <fxui:Interaction.Behaviors>
        <fxui:MouseWheelScroll />
      </fxui:Interaction.Behaviors>
      <TextBox.Text>Lorem ipsum dolor sit amet...</TextBox.Text>
    </TextBox> 

  </Grid>
</UserControl>

Thats pretty much it! You don't have to write any code, much less deal with browser APIs to handle mouse scroll events! If browser access is turned off, this just degrades gracefully. Regular scrolling continues to work of course. I really love the behavior concept for the way it enables adding interactivity to your XAML, while keeping it clean, declarative and super-simple.

Posted on Friday, 4/10/2009 @ 11:20 PM | #Silverlight


Comments

28 comments have been posted.

Jeff Handley

Posted on 4/10/2009 @ 11:29 PM
Sweet!

ibillguo

Posted on 4/11/2009 @ 1:28 AM
great, thanks

mikekidder

Posted on 4/11/2009 @ 9:50 AM
Nikhil, doesn't appear to work for SL3b1 under OSX 10.5.6 (microsoft wheel mouse). Mouse scroll is working for the browsers under OSX (firefox and safari). Ironically enough, the demo's are working great on my VMWare Fusion; OSX -> VMWare Fusion -> XP -> FF3 -> SL3b1 == awesome.

Vitor Canova

Posted on 4/11/2009 @ 5:38 PM
As easy as must be.

Steve Gentile

Posted on 4/11/2009 @ 6:21 PM
"note that this does work with Silverlight 2 as well"

Does that mean you have updated Silverlight.FX to 3.0 ?

Nikhil Kothari

Posted on 4/12/2009 @ 9:40 AM
@Steve - I first wrote my sample on a machine with Silverlight 3, and then recompiled it on SL2.
I haven't yet started the Silverlight.FX update, but most things should work. There are two categories of changes that I am anticipating:
- Things that can be done better (eg. not needing a derived application type)
- Things that can be replaced with platform equivalents (possibly themes using MergedDictionary - still thinking about it though)

All the features themselves should hopefully continue to work unchanged...

Hatim Rih

Posted on 4/13/2009 @ 10:52 AM
Nicely done!

Zed

Posted on 4/13/2009 @ 12:57 PM
Nice... but does it work in full screen mode?

Steve Gentile

Posted on 4/13/2009 @ 1:29 PM
Nikhil, will there be a way to use your types you have created in order to work in Blend with SL 3 ?

ie. Would be nice to visually use your layout views, windows, etc... in Blend.

Nikhil Kothari

Posted on 4/13/2009 @ 1:34 PM
@Zed - no this doesn't work in full screen mode, since the control is outside of the browser. I think SL3 will have some more support for mouse wheel (don't know if it was in the beta, and which platforms), so I'll update this behavior to use that when applicable. Another thing for the SL3 list...

@Steve - Blend support overall is somewhat of a big cross-cutting thing I need to start looking into. On behaviors specifically Blend will have some tooling for the behaviors it is introducing. The nice thing is all the experience building behaviors in Silverlight.FX was factored in into the Blend API, so atleast the fundamentals are the same... you'll notice in Silverlight.FX sources, the core behavior system is under a folder called Platform, which I'd like to be subsumed into the platform over time.

Utkarsh Puranik

Posted on 4/14/2009 @ 3:15 AM
thanks I had to do a lot of work to implement this before.......this is pretty easy :)

Leslie Winston

Posted on 4/15/2009 @ 4:41 PM
I am having two problems with the MouseWheelScrolling: ScrollSize and Scrolls within Scolls.
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<fxui:Interaction.Behaviors>
<fxui:MouseWheelScroll />
</fxui:Interaction.Behaviors>
1)
I have a layout with a grid with 3 rows (30, *, 40)
Inside the main middle row is a ScrollViewer with the fxui MouseWheelScroll behavior.
Inside the ScrollViewer is another grid with 4 columns and somewhere down in one of the columns is a textbox also implementing the fxui MouseScrollWheel.
When the brower first opens full screen, the inner scroll with mouse works but the outer scroll doesn’t.
If the browser is restored to a windowed size, then the outer scroll begins to work but the inner scroll affects both the inner and the outer. In either direction, the outer scroll has to get to the end of its range before the inner scroll starts to move.
<TextBox AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto">
<fxui:Interaction.Behaviors>
<fxui:MouseWheelScroll ScrollSize="3" />
</fxui:Interaction.Behaviors>
2)
ScrollSize does not seem to have any effect (in fact it is very slow).
Thank you – your framework is a truly beautiful thing.

Nikhil Kothari

Posted on 4/16/2009 @ 7:52 AM
@Leslie - It might very well be that there are bugs with nested scrollbars. Something to fix...
At the same time, I'd raise a question if that is appropriate UX - I've seen some apps with multiple vertical scrollbars, and they're a pain, regardless of mouse wheel or not. Might be interesting to consider a design such that at any given time, there will only be one vertical scrollbar in the app, if at all possible...

Leslie Winston

Posted on 4/16/2009 @ 11:47 AM
I would agree - in this case the outer scroll serves instead of the browser scroll (the layout root has a thin row at bottom and top for menus and status, the silverlight space takes up the whole browser so the browser scroll never shows - just the scrolls for the main content row) the inner scroll is just on a textbox that wraps a lot of text and only is visible when that functionality is needed.

On the other subject - am I using ScrollSize correctly? It dosen't seem to matter what number I enter.
Thanks again.
Leslie

JC

Posted on 4/23/2009 @ 5:14 AM
Thanks Nikhil, awesome work! I wanted to add to Leslie's question about ScrollSize - the mouse scroll seems to slow for me and setting ScrollSize doesn't speed it up. Is that property functional?

Nikhil Kothari

Posted on 4/30/2009 @ 9:48 PM
@Leslie, @JC - I will look into whats up with the ScrollSize property - its likely I didn't implement it... :-)

Matt

Posted on 5/3/2009 @ 4:14 AM
Nikhil,
Just checked out the live demo. The scroll functionality works great in firefox 3, but doesnt work in IE8 and Chrome. Any ideas?
Thanks

Edukondalu

Posted on 5/14/2009 @ 7:48 AM
Hi what is this SliverlightFX it is third party dll or it is silverlight's own dll. Can we use this dll in production sites.
Please give me some information on SilverLightFx.

Thanks,
Konda.

Justin Toth

Posted on 5/18/2009 @ 5:01 PM
This doesn't seem to work... I downloaded the latest Silverlight.FX code, referenced the SilverlightFX\binaries\Release\Silverlight\SilverlightFX.dll, added xmlns:fxui="clr-namespace:SilverlightFX.UserInterface;assembly=SilverlightFX" to the top of my page, and added the behavior to my ScrollViewer:

<ScrollViewer Style="{StaticResource PageScroller}">
<fxui:Interaction.Behaviors>
<fxui:MouseWheelScroll />
</fxui:Interaction.Behaviors>
<StackPanel x:Name="spContent" Orientation="Vertical" Margin="10,10,10,10" HorizontalAlignment="Left" />
</ScrollViewer>

The mouse wheel doesn't work no matter what I try, very disappointing... I am using SL2.

Nikhil Kothari

Posted on 5/22/2009 @ 10:25 PM
@Edukondalu - http://projects.nikhilk.net/SilverlightFX

@Justin Toth - is HTML DOM access enabled for the silverlight control (via the enableHtmlAccess param tag)? This is needed to handle DOM events for supporting mouse scroll functionality.

Korash

Posted on 5/25/2009 @ 1:14 PM
Nikhil,
Wow, this is terrific functionality! One question, I's like to use the <fxui:MouseWheelScroll/> functionality with a ComboBox. While this code works great for ListBoxes it doesn't seem to work for ComboBoxes. Am I just not implementing it correctly or was it never intended for use with a ComboBox?

Vimal Saifudin

Posted on 7/2/2009 @ 10:01 AM
How can we create a auto horizontal scrolling marquee of images in silverlight using ScrollViewer

Hoangtu

Posted on 8/27/2009 @ 7:51 PM
How to add MouseWheel Behavior in code behind?

kulwinder singh

Posted on 8/29/2009 @ 3:29 AM
it works great...but i want to scroll my scrollviewer horizontally on the scroll of mouse wheel how to do that??

David Suarez

Posted on 9/10/2009 @ 4:34 AM
I think that the behavior is not the same as in the browser, because when there is a ScrollViewer inside another, the second one receive the event and both moves at a time.

I've been seeing that in the version 3.0 of silverlight already implement MouseWheel event.

To solve this I think the following:

1) In the OnAttach event of the MouseWheelScrollBehavior class attach to the MouseWheel event of AssociatedObject

protected override void OnAttach ()
(
base.OnAttach ();
AssociatedObject.MouseWheel + = new MouseWheelEventHandler (AssociatedObject_MouseWheel);
)

private void AssociatedObject_MouseWheel (object sender, MouseWheelEventArgs e)
(
ConfigureScrollProvider ();
e.Handled = UpdateScrollOffset (e.Delta);
)

2º) While the ScrollOffset value is between 0 to 100, I' don't propagate the event to the container objects. When the ScrollOffset value is less than 0 or more than 100 then yes propagate the event:

(_scrollProvider.VerticalScrollPercent> 0 & & _scrollProvider.VerticalScrollPercent <100);


The code would be this:

UpdateScrollOffset private bool (int delta)
(
if ((_scrollProvider! = null) & & _scrollProvider.VerticallyScrollable)
(
ScrollAmount VerticalScroll = delta <0? ScrollAmount.SmallIncrement: ScrollAmount.SmallDecrement;
_scrollProvider.Scroll (ScrollAmount.NoAmount, VerticalScroll);

return (_scrollProvider.VerticalScrollPercent> 0 & & _scrollProvider.VerticalScrollPercent <100);
)

return false;
)


What do you think?

Morten

Posted on 10/2/2009 @ 9:11 AM
As far as I can tell this looks exactly like the Blend SDK behaviors. Any reason why you are not using that instead?
Using the SDK should give you much better integration in Blend (just drag the behavior onto your elements).

Nikhil

Posted on 10/14/2009 @ 1:02 PM
Hi Is it work while my control is disabled. i have 10 control in the page. few of them are disabled. When I wheel mouse on the controls its not working while in case of enabled control its works great.
Please let me know do I have to change any thing in my code to make it work.

Prompt reply would be appreciated.

Regards,
Nikhil

Neeta

Posted on 1/14/2010 @ 1:37 PM
Hi Nikhil,
This works great with Textbox and Listbox.However it fails with ComboBox.Any idea why ?

Thanks,
Neeta
Post your comment and continue the discussion.