Datagrid in silverlight 3 toolkit is not responding to scrollwheel(mousewheel). Is there any way to get support of scroll wheel?
Below is the behavior I am using. And below that is how you attach it to the datagrid in xaml.
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Automation.Peers;
using System.Windows.Interactivity;
using System.Windows.Automation.Provider;
using System.Windows.Automation;
using System.Windows.Data;
namespace GLS.Gui.Helper.Behaviors
{
public class MouseWheelScrollBehavior : Behavior<Control>
{
/// <summary>
/// Gets or sets the peer.
/// </summary>
/// <value>The peer.</value>
private AutomationPeer Peer { get; set; }
/// <summary>
/// Called after the behavior is attached to an AssociatedObject.
/// </summary>
/// <remarks>Override this to hook up functionality to the AssociatedObject.</remarks>
protected override void OnAttached()
{
this.Peer = FrameworkElementAutomationPeer.FromElement(this.AssociatedObject);
if (this.Peer == null)
this.Peer = FrameworkElementAutomationPeer.CreatePeerForElement(this.AssociatedObject);
this.AssociatedObject.MouseWheel += new MouseWheelEventHandler(AssociatedObject_MouseWheel);
base.OnAttached();
}
/// <summary>
/// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.
/// </summary>
/// <remarks>Override this to unhook functionality from the AssociatedObject.</remarks>
protected override void OnDetaching()
{
this.AssociatedObject.MouseWheel -= new MouseWheelEventHandler(AssociatedObject_MouseWheel);
base.OnDetaching();
}
/// <summary>
/// Handles the MouseWheel event of the AssociatedObject control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Windows.Input.MouseWheelEventArgs"/> instance containing the event data.</param>
void AssociatedObject_MouseWheel(object sender, MouseWheelEventArgs e)
{
//Do not handle already handled events
if (e.Handled)
return;
this.AssociatedObject.Focus();
int direction = Math.Sign(e.Delta);
ScrollAmount scrollAmount =
(direction < 0) ? ScrollAmount.SmallIncrement : ScrollAmount.SmallDecrement;
if (this.Peer != null)
{
IScrollProvider scrollProvider =
this.Peer.GetPattern(PatternInterface.Scroll) as IScrollProvider;
bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
if (scrollProvider != null && scrollProvider.VerticallyScrollable && !shiftKey)
{
scrollProvider.Scroll(ScrollAmount.NoAmount, scrollAmount);
e.Handled = true;
}
else if (scrollProvider != null && scrollProvider.VerticallyScrollable && shiftKey)
{
scrollProvider.Scroll(scrollAmount, ScrollAmount.NoAmount);
e.Handled = true;
}
}
}
}
}
How to attach the behavior:
<data:DataGrid>
<i:Interaction.Behaviors>
<b:MouseWheelScrollBehavior />
</i:Interaction.Behaviors>
</data:DataGrid>
An other way to do this (very basic example):
xaml:
<Grid x:Name="LayoutRoot">
<data:DataGrid x:Name="dg" Height="100">
<ScrollViewer.VerticalScrollBarVisibility>true</ScrollViewer.VerticalScrollBarVisibility>
</data:DataGrid>
CS:
public partial class MainPage : UserControl
{
IList<Person> list = new List<Person>();
public MainPage()
{
InitializeComponent();
list.Add(new Person("Pieter1","Nijs"));
list.Add(new Person("Pieter2", "Nijs"));
list.Add(new Person("Pieter3", "Nijs"));
list.Add(new Person("Pieter4", "Nijs"));
list.Add(new Person("Pieter5", "Nijs"));
list.Add(new Person("Pieter6", "Nijs"));
list.Add(new Person("Pieter7", "Nijs"));
list.Add(new Person("Pieter8", "Nijs"));
dg.ItemsSource = list;
dg.MouseWheel += new MouseWheelEventHandler(dg_MouseWheel);
}
void dg_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta < 0)
{
dg.ScrollIntoView(list[dg.SelectedIndex + 2], null);
}
else
{
dg.ScrollIntoView(list[dg.SelectedIndex - 2], null);
}
}
}
So, what I do here is quite simple!
I add an EventHandler to the DataGrid MouseWheel
- event. In that handler I retreive the e.Delta
(this is the amount the wheel has changed since the last time) so I know if the user scrolled up (positive Delta) or down (negative Delta). And then I call the ScrollIntoView
-method of the DataGrid, where I can specify to what row the Grid should scroll to.
As mentioned, this is a very basic example! This is just to show you how it could work! You should add extra logic to make sure you don't go out of bounce!
I have used the MouseWheel Behavior for Silverlight from Silverlight.FX as a way to add mousewheel support to my apps. See http://www.nikhilk.net/Silverlight-MouseWheel.aspx for details.
I am using the Silverlight Toolkit ScrollViewerExtensions in combination with a custom template for the datagrid. But i have the problem that the DataGrid does not look the same way it did before i applied the template... Someone can help me out?
<Style x:Key="StyleTable" TargetType="wcd:DataGrid">
<Setter Property="CellStyle" Value="{StaticResource StyleTableCell}"/>
<Setter Property="ColumnHeaderStyle" Value="{StaticResource StyleTableColumnHeader}"/>
<Setter Property="RowHeaderStyle" Value="{StaticResource StyleTableRowHeader}"/>
<Setter Property="RowStyle" Value="{StaticResource StyleTableRow}"/>
<Setter Property="SelectionMode" Value="Single"/>
<Setter Property="IsReadOnly" Value="true"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="GridLinesVisibility" Value="Horizontal"/>
<Setter Property="ColumnTextStyle" Value="{StaticResource StyleColumnText}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="wcd:DataGrid">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<dataPrimitives:DataGridColumnHeadersPresenter x:Name="ColumnHeadersPresenter" />
<ScrollViewer Grid.Row="1" toolkit:ScrollViewerExtensions.IsMouseWheelScrollingEnabled="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
<dataPrimitives:DataGridRowsPresenter x:Name="RowsPresenter" />
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>