我试图以明显的方式处理ScrollViewer.ScrollChanged的路由事件DataGrid

<i:Interaction.Triggers>
    <i:EventTrigger EventName="ScrollViewer.ScrollChanged">
       <ei:CallMethodAction MethodName="ScrollChangedHandler" TargetObject="{Binding}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>


但是ScrollChangedHandler甚至没有解雇。

然后,我找到了this article about handling events,但是我不知道xmlns使用了什么xml名称空间(mvvmjaco):

<Image Width="360" Height="177" Source="Resources\PlayerArea.png">
   <i:Interaction.Triggers>
      <mvvmjoy:RoutedEventTrigger RoutedEvent="s:Contacts.ContactDown">
          <mvvmjaco:CommandAction Command="{Binding TouchCommand}" />
      </mvvmjoy:RoutedEventTrigger>
   </i:Interaction.Triggers>
</Image>


mvvmjoy使用此类from the article

public class RoutedEventTrigger :EventTriggerBase<DependencyObject>
{
    RoutedEvent _routedEvent;
    //The code omitted for the brevity
}


基本上,我有两个问题:


我应该为mvvmjaco xml名称空间使用什么类或库?
如何使用其参数处理viewModel中的ScrollViewer.ScrollChanged事件?

最佳答案

我将使用以下附加属性来解决它:

using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApplication2
{
    public class DataGridExtensions
    {
        public static readonly DependencyProperty ScrollChangedCommandProperty = DependencyProperty.RegisterAttached(
            "ScrollChangedCommand", typeof(ICommand), typeof(DataGridExtensions),
            new PropertyMetadata(default(ICommand), OnScrollChangedCommandChanged));

        private static void OnScrollChangedCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid dataGrid = d as DataGrid;
            if (dataGrid == null)
                return;
            if (e.NewValue != null)
            {
                dataGrid.Loaded += DataGridOnLoaded;
            }
            else if (e.OldValue != null)
            {
                dataGrid.Loaded -= DataGridOnLoaded;
            }
        }

        private static void DataGridOnLoaded(object sender, RoutedEventArgs routedEventArgs)
        {
            DataGrid dataGrid = sender as DataGrid;
            if (dataGrid == null)
                return;

            ScrollViewer scrollViewer = UIHelper.FindChildren<ScrollViewer>(dataGrid).FirstOrDefault();
            if (scrollViewer != null)
            {
                scrollViewer.ScrollChanged += ScrollViewerOnScrollChanged;
            }
        }

        private static void ScrollViewerOnScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            DataGrid dataGrid = UIHelper.FindParent<DataGrid>(sender as ScrollViewer);
            if (dataGrid != null)
            {
                ICommand command = GetScrollChangedCommand(dataGrid);
                command.Execute(e);
            }
        }

        public static void SetScrollChangedCommand(DependencyObject element, ICommand value)
        {
            element.SetValue(ScrollChangedCommandProperty, value);
        }

        public static ICommand GetScrollChangedCommand(DependencyObject element)
        {
            return (ICommand)element.GetValue(ScrollChangedCommandProperty);
        }
    }
}


UIHelper看起来像:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;

namespace WpfApplication2
{
    internal static class UIHelper
    {
        internal static IList<T> FindChildren<T>(DependencyObject element) where T : FrameworkElement
        {
            List<T> retval = new List<T>();
            for (int counter = 0; counter < VisualTreeHelper.GetChildrenCount(element); counter++)
            {
                FrameworkElement toadd = VisualTreeHelper.GetChild(element, counter) as FrameworkElement;
                if (toadd != null)
                {
                    T correctlyTyped = toadd as T;
                    if (correctlyTyped != null)
                    {
                        retval.Add(correctlyTyped);
                    }
                    else
                    {
                        retval.AddRange(FindChildren<T>(toadd));
                    }
                }
            }
            return retval;
        }

        internal static T FindParent<T>(DependencyObject element) where T : FrameworkElement
        {
            FrameworkElement parent = VisualTreeHelper.GetParent(element) as FrameworkElement;
            while (parent != null)
            {
                T correctlyTyped = parent as T;
                if (correctlyTyped != null)
                {
                    return correctlyTyped;
                }
                return FindParent<T>(parent);
            }
            return null;
        }
    }
}


然后,您可以编写DataGrid的定义:

<DataGrid ItemsSource="{Binding MySource}" extensionsNamespace:DataGridExtensions.ScrollChangedCommand="{Binding ScrollCommand}"/>


在ViewModel中,您有一个ICommand,它看起来像:

private ICommand scrollCommand;
public ICommand ScrollCommand
{
    get { return scrollCommand ?? (scrollCommand = new RelayCommand(Scroll)); }
}

private void Scroll(object parameter)
{
    ScrollChangedEventArgs scrollChangedEventArgs = parameter as ScrollChangedEventArgs;
    if (scrollChangedEventArgs != null)
    {

    }
}


对于您的第一个问题(特别感谢Andy ONeill and Magnus Montin):

MVVMJaco是xmlns:mvvmjaco =“ galasoft.ch/mvvmlight”
所需的库是:


GalaSoft.MVVmLight
GalaSoft.MVVmLight.Extras
GalaSoft.MVVmLight.Platform

07-27 21:35