Click here to Skip to main content
15,886,873 members
Articles / Desktop Programming / WPF

Improving WPF Mouse Wheel Processing

Rate me:
Please Sign up or sign in to vote.
4.91/5 (29 votes)
11 Jun 2016MIT16 min read 94K   3.8K   52  
How to quickly improve your WPF application to give your users a pleasant mouse wheel experience
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Media3D;

namespace Logitech.Windows
{
  #region VisualTreeServices
  public static class VisualTreeServices
  {
    public static DependencyObject GetRoot(DependencyObject reference)
    {
      if (reference == null) return null;
      DependencyObject parent = VisualTreeHelper.GetParent(reference);
      while (parent != null)
      {
        reference = parent;
        parent = VisualTreeHelper.GetParent(reference);
      }
      return reference;
    }
    public static IEnumerable<DependencyObject> GetAncestors(DependencyObject reference)
    {
      if (reference == null) yield break;
      DependencyObject parent = VisualTreeHelper.GetParent(reference);
      while (parent != null)
      {
        yield return parent;
        parent = VisualTreeHelper.GetParent(parent);
      }
    }
    public static IEnumerable<DependencyObject> GetChildren(DependencyObject reference)
    {
      if (reference is Visual || reference is Visual3D)
      {
        int count = VisualTreeHelper.GetChildrenCount(reference);
        for (int i = 0; i < count; i++)
          yield return VisualTreeHelper.GetChild(reference, i);
      }
    }
    public static IEnumerable<DependencyObject> GetDescendants(DependencyObject reference)
    {
      if (reference == null) yield break;
      foreach (DependencyObject child in GetChildren(reference))
        foreach (DependencyObject item in GetTree(child))
          yield return item;
    }
    public static IEnumerable<DependencyObject> GetTree(DependencyObject reference)
    {
      if (reference == null) yield break;
      yield return reference;
      foreach (DependencyObject child in GetChildren(reference))
        foreach (DependencyObject item in GetTree(child))
          yield return item;
    }

    public static IEnumerable<T> GetTreeItemsOfType<T>(DependencyObject reference) where T : class
    {
      if (reference == null) yield break;
      foreach (DependencyObject item in GetTree(reference))
      {
        T asT = item as T;
        if (asT != null) yield return asT;
      }
    }
    public static IEnumerable<T> GetDescendantsOfType<T>(DependencyObject reference) where T : class
    {
      if (reference == null) yield break;
      foreach (DependencyObject item in GetDescendants(reference))
      {
        T asT = item as T;
        if (asT != null) yield return asT;
      }
    }
    public static IEnumerable<T> GetAncestorsOfType<T>(DependencyObject reference) where T : class
    {
      if (reference == null) yield break;
      foreach (DependencyObject ancestor in GetAncestors(reference))
      {
        T asT = ancestor as T;
        if (asT != null) yield return asT;
      }
    }
    public static T GetFirstTreeItemOfType<T>(DependencyObject reference) where T : class
    {
      if (reference == null) return null;
      foreach (T item in GetTreeItemsOfType<T>(reference))
        return item;
      return null;
    }
    public static T GetFirstDescendantOfType<T>(DependencyObject reference) where T : class
    {
      if (reference == null) return null;
      foreach (T item in GetDescendantsOfType<T>(reference))
        return item;
      return null;
    }
    public static T GetFirstAncestorOfType<T>(DependencyObject reference) where T : class
    {
      if (reference == null) return null;
      foreach (T item in GetAncestorsOfType<T>(reference))
        return item;
      return null;
    }
  } 
  #endregion

  #region LogicalTreeServices
  public static class LogicalTreeServices
  {
    public static DependencyObject GetRoot(DependencyObject reference)
    {
      DependencyObject parent = LogicalTreeHelper.GetParent(reference);
      while (parent != null)
      {
        reference = parent;
        parent = LogicalTreeHelper.GetParent(reference);
      }
      return reference;
    }
    public static IEnumerable<DependencyObject> GetAncestors(DependencyObject reference)
    {
      DependencyObject parent = LogicalTreeHelper.GetParent(reference);
      while (parent != null)
      {
        yield return parent;
        parent = LogicalTreeHelper.GetParent(parent);
      }
    }
    public static IEnumerable GetChildren(DependencyObject reference)
    {
      return LogicalTreeHelper.GetChildren(reference);
    }
    public static IEnumerable GetDescendants(DependencyObject reference)
    {
      foreach (object child in LogicalTreeHelper.GetChildren(reference))
      {
        if (child is DependencyObject)
        {
          foreach (object item in GetTree(child as DependencyObject))
            yield return item;
        }
        else
          yield return child;
      }
    }
    public static IEnumerable GetTree(DependencyObject reference)
    {
      yield return reference;
      foreach (object item in GetDescendants(reference))
        yield return item;
    }

    public static IEnumerable<T> GetTreeItemsOfType<T>(DependencyObject reference) where T : class
    {
      foreach (object item in GetTree(reference))
      {
        T asT = item as T;
        if (asT != null) yield return asT;
      }
    }
    public static IEnumerable<T> GetDescendantsOfType<T>(DependencyObject reference) where T : class
    {
      foreach (object item in GetDescendants(reference))
      {
        T asT = item as T;
        if (asT != null) yield return asT;
      }
    }
    public static IEnumerable<T> GetAncestorsOfType<T>(DependencyObject reference) where T : class
    {
      foreach (DependencyObject ancestor in GetAncestors(reference))
      {
        T asT = ancestor as T;
        if (asT != null) yield return asT;
      }
    }
    public static T GetFirstTreeItemOfType<T>(DependencyObject reference) where T : class
    {
      foreach (T item in GetTreeItemsOfType<T>(reference))
        return item;
      return null;
    }
    public static T GetFirstDescendantOfType<T>(DependencyObject reference) where T : class
    {
      foreach (T item in GetDescendantsOfType<T>(reference))
        return item;
      return null;
    }
    public static T GetFirstAncestorOfType<T>(DependencyObject reference) where T : class
    {
      foreach (T item in GetAncestorsOfType<T>(reference))
        return item;
      return null;
    }
  } 
  #endregion

  #region DependencyObjectExtensions
  public static class DependencyObjectExtensions
  {
    public static DependencyObject                     GetLogicalRoot(this DependencyObject reference) { return LogicalTreeServices.GetRoot(reference); }
    public static IEnumerable<DependencyObject>   GetLogicalAncestors(this DependencyObject reference) { return LogicalTreeServices.GetAncestors(reference); }
    public static IEnumerable                      GetLogicalChildren(this DependencyObject reference) { return LogicalTreeServices.GetChildren(reference); }
    public static IEnumerable                   GetLogicalDescendants(this DependencyObject reference) { return LogicalTreeServices.GetDescendants(reference); }
    public static IEnumerable                          GetLogicalTree(this DependencyObject reference) { return LogicalTreeServices.GetTree(reference); }
    public static IEnumerable<T>         GetLogicalTreeItemsOfType<T>(this DependencyObject reference) where T : class { return LogicalTreeServices.GetTreeItemsOfType<T>(reference); }
    public static IEnumerable<T>       GetLogicalDescendantsOfType<T>(this DependencyObject reference) where T : class { return LogicalTreeServices.GetDescendantsOfType<T>(reference); }
    public static IEnumerable<T>         GetLogicalAncestorsOfType<T>(this DependencyObject reference) where T : class { return LogicalTreeServices.GetAncestorsOfType<T>(reference); }
    public static T                  GetFirstLogicalTreeItemOfType<T>(this DependencyObject reference) where T : class { return LogicalTreeServices.GetFirstTreeItemOfType<T>(reference); }
    public static T                GetFirstLogicalDescendantOfType<T>(this DependencyObject reference) where T : class { return LogicalTreeServices.GetFirstDescendantOfType<T>(reference); }
    public static T                  GetFirstLogicalAncestorOfType<T>(this DependencyObject reference) where T : class { return LogicalTreeServices.GetFirstAncestorOfType<T>(reference); }

    public static DependencyObject                     GetVisualRoot(this DependencyObject reference) { return VisualTreeServices.GetRoot(reference); }
    public static IEnumerable<DependencyObject>   GetVisualAncestors(this DependencyObject reference) { return VisualTreeServices.GetAncestors(reference); }
    public static IEnumerable<DependencyObject>    GetVisualChildren(this DependencyObject reference) { return VisualTreeServices.GetChildren(reference); }
    public static IEnumerable<DependencyObject> GetVisualDescendants(this DependencyObject reference) { return VisualTreeServices.GetDescendants(reference); }
    public static IEnumerable<DependencyObject>        GetVisualTree(this DependencyObject reference) { return VisualTreeServices.GetTree(reference); }
    public static IEnumerable<T>         GetVisualTreeItemsOfType<T>(this DependencyObject reference) where T : class { return VisualTreeServices.GetTreeItemsOfType<T>(reference); }
    public static IEnumerable<T>       GetVisualDescendantsOfType<T>(this DependencyObject reference) where T : class { return VisualTreeServices.GetDescendantsOfType<T>(reference); }
    public static IEnumerable<T>         GetVisualAncestorsOfType<T>(this DependencyObject reference) where T : class { return VisualTreeServices.GetAncestorsOfType<T>(reference); }
    public static T                  GetFirstVisualTreeItemOfType<T>(this DependencyObject reference) where T : class { return VisualTreeServices.GetFirstTreeItemOfType<T>(reference); }
    public static T                GetFirstVisualDescendantOfType<T>(this DependencyObject reference) where T : class { return VisualTreeServices.GetFirstDescendantOfType<T>(reference); }
    public static T                  GetFirstVisualAncestorOfType<T>(this DependencyObject reference) where T : class { return VisualTreeServices.GetFirstAncestorOfType<T>(reference); }


    public static IEnumerable<BindingExpression> EnumerateBindings(this DependencyObject reference)
    {
      LocalValueEnumerator enumerator = reference.GetLocalValueEnumerator();
      while (enumerator.MoveNext())
      {
        LocalValueEntry entry = enumerator.Current;
        if (BindingOperations.IsDataBound(reference, entry.Property))
          yield return entry.Value as BindingExpression;
      }
    }
  }
  #endregion
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Software Developer (Senior)
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions