从C#访问ListBox的ScrollViewer

dha*_*ech 14 c# wpf xaml listbox scrollviewer

我想的属性改变ScrollViewerListBox从C#.

我在Stackoverflow上找到了这个问题.我接受了接受的答案的建议,并将其ScrollViewer作为子类的属性公开.但是,这似乎不适用于下面显示的示例.该问题中的一些评论也表明这种技术不起作用.

XAML:

<Window x:Class="StackoverflowListBoxScrollViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

</Window>
Run Code Online (Sandbox Code Playgroud)

C#:

using System;
using System.Windows;
using System.Windows.Controls;

namespace StackoverflowListBoxScrollViewer
{
    public class MyListBox : ListBox
    {
        public ScrollViewer ScrollViewer
        { get { return (ScrollViewer)GetTemplateChild("ScrollViewer"); } }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var myListBox = new MyListBox();

            Content = myListBox;

            myListBox.Items.Add(new Button() { Content = "abc" });
            myListBox.Items.Add(new Button() { Content = "abc" });
            myListBox.Items.Add(new Button() { Content = "abc" });
            myListBox.Items.Add(new Button() { Content = "abc" });
            myListBox.Items.Add(new Button() { Content = "abc" });

            var button = new Button() { Content = "Check ScrollViewer" };
            button.Click += (s, e) =>
                {
                    if (myListBox.ScrollViewer == null)
                        Console.WriteLine("null");
                };
            myListBox.Items.Add(button);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我单击"检查ScrollViewer"按钮时,它会打印"null".即,ScrollViewer没有检索.

我怎么得到这个蠢货ScrollViewer?:-)

pun*_*r76 23

你可以试试这个小帮手功能

用法

var scrollViewer = GetDescendantByType(yourListBox, typeof(ScrollViewer)) as ScrollViewer;
Run Code Online (Sandbox Code Playgroud)

辅助功能

public static Visual GetDescendantByType(Visual element, Type type)
{
  if (element == null) {
    return null;
  }
  if (element.GetType() == type) {
    return element;
  }
  Visual foundElement = null;
  if (element is FrameworkElement) {
    (element as FrameworkElement).ApplyTemplate();
  }
  for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) {
    Visual visual = VisualTreeHelper.GetChild(element, i) as Visual;
    foundElement = GetDescendantByType(visual, type);
    if (foundElement != null) {
      break;
    }
  }
  return foundElement;
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助


stu*_*bax 8

如果你将使用标准的ListBox,那么你可以改变你的getter到这个:

public class MyListBox : ListBox
{
    public ScrollViewer ScrollViewer
    {
        get 
        {
            Border border = (Border)VisualTreeHelper.GetChild(this, 0);

            return (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在类型之后命名属性没有任何问题.事实上,它是推荐的做法:http://msdn.microsoft.com/en-us/library/ms229012.aspx. (4认同)
  • ...您真的不应该将您的 ScrollViewer-Property 称为“ScrollViewer”。 (2认同)

Sam*_*uel 6

我已经修改了@ punker76的优秀答案来为Visual创建一个扩展方法并提供显式返回类型:

   public static class Extensions
   {
      public static T GetDescendantByType<T>(this Visual element) where T:class
      {
         if (element == null)
         {
            return default(T);
         }
         if (element.GetType() == typeof(T))
         {
            return element as T;
         }
         T foundElement = null;
         if (element is FrameworkElement)
         {
            (element as FrameworkElement).ApplyTemplate();
         }
         for (var i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
         {
            var visual = VisualTreeHelper.GetChild(element, i) as Visual;
            foundElement = visual.GetDescendantByType<T>();
            if (foundElement != null)
            {
               break;
            }
         }
         return foundElement;
      }

   }
Run Code Online (Sandbox Code Playgroud)

您现在可以通过SomeVisual.GetDescendantByType调用它,它返回已经是正确类型的ScrollViewer或null(默认为(T))