扩展方法是.NET 3.0中的一个技术亮点,它允许我们对一些对象的方法进行自定义的扩展。这样一来,我们可以将对函数的调用写成类似于object.ToString()这样的方法的调用。
  下面将介绍对ListView控件的几个扩展方法。
  1、GetItem和IsInRow。
  GetItem和IsInRow是两个类似的方法,前者用于取出当前鼠标当前选中的行,后者用于判断当前鼠标是否在行中。它的实现是基于VisualTreeHelper.HitTest方法的。
    1         public static bool IsInRow(this ListView control)
    2         {
    3             try
    4             {
    5                 bool value = true;
    6 
    7                 HitTestResult result = VisualTreeHelper.HitTest(control, Mouse.GetPosition(control));
    8                 object context = (result.VisualHit as FrameworkElement).DataContext;
    9 
   10                 if (context is object[]) value = false;
   11 
   12                 return value;
   13             }
   14             catch
   15             {
   16                 throw;
   17             }
   18         }
   19 
   20         public static object GetItem(this ListView control)
   21         {
   22             try
   23             {
   24                 object item = null;
   25 
   26                 HitTestResult result = VisualTreeHelper.HitTest(control, Mouse.GetPosition(control));
   27                 object context = (result.VisualHit as FrameworkElement).DataContext;
   28 
   29                 if ((context is object[]) == false) item = context;
   30 
   31                 return item;
   32             }
   33             catch
   34             {
   35                 throw;
   36             }
   37         }
  2、GetControl和GetPresenter。
  为了能找到模板列中的控件,我们首先采用递归循环的方法(GetPresenter)来找到容纳该控件的容器,然后再找到该控件(GetControl)。它的实现是基于VisualTreeHelper.GetChild方法和ContentTemplate.FindName方法的。
    1         public static Control GetControl(this ListView control, string name)
    2         {
    3             try
    4             {
    5                 object item = control.GetItem();
    6                 ContentPresenter presenter = control.ItemContainerGenerator.ContainerFromItem(item).GetPresenter(name);
    7 
    8                 return (Control)presenter.ContentTemplate.FindName(name, presenter);
    9             }
   10             catch
   11             {
   12                 throw;
   13             }
   14         }
    1         public static ContentPresenter GetPresenter(this DependencyObject reference, string name)
    2         {
    3             try
    4             {
    5                 for (int i = 0; i < VisualTreeHelper.GetChildrenCount(reference); i++)
    6                 {
    7                     DependencyObject child = VisualTreeHelper.GetChild(reference, i);
    8 
    9                     if (child != null && child is ContentPresenter)
   10                     {
   11                         ContentPresenter presenter = child as ContentPresenter;
   12 
   13                         object element = presenter.ContentTemplate.FindName(name, presenter);
   14 
   15                         if (element != null) return presenter;
   16                     }
   17                     else
   18                     {
   19                         ContentPresenter presenter = child.GetPresenter(name);
   20 
   21                         if (presenter != null) return presenter;
   22                     }
   23                 }
   24 
   25                 return null;
   26             }
   27             catch
   28             {
   29                 throw;
   30             }