Сетка данных Silverlight 3: Как добавить поддержку колесика прокрутки? - PullRequest
2 голосов
/ 16 февраля 2010

Набор данных в Silverlight 3 toolkit не отвечает на колесо прокрутки (колесо мыши). Есть ли способ получить поддержку колеса прокрутки?

Ответы [ 2 ]

3 голосов
/ 16 февраля 2010

Ниже приводится описание поведения, которое я использую. А ниже вы прикрепляете его к сетке данных в 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;
                }


            }
        }
    }


}

Как прикрепить поведение:

<data:DataGrid>
            <i:Interaction.Behaviors>
                <b:MouseWheelScrollBehavior />
            </i:Interaction.Behaviors>
        </data:DataGrid>
0 голосов
/ 16 февраля 2010

Другой способ сделать это (очень простой пример):
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);
        }
    }
}

Итак, что я здесь делаю, очень просто!
Я добавляю EventHandler к событию DataGrid MouseWheel. В этом обработчике я получаю e.Delta (это количество, которое колесо изменило с прошлого раза), поэтому я знаю, прокручивал ли пользователь вверх (положительная дельта) или вниз (отрицательная дельта). И тогда я вызываю ScrollIntoView -метод DataGrid, где я могу указать, к какой строке должна быть прокрутка Grid.
Как уже упоминалось, это очень простой пример! Это просто чтобы показать вам, как это может работать! Вы должны добавить дополнительную логику, чтобы убедиться, что вы не выходите из отказов!

...