为什么FrameworkElement.FindName(string)方法在我的情况下返回null?

时间:2017-01-08 13:35:56

标签: c# .net wpf

WPF,.NET 4.6.1

为什么FrameworkElement.FindName(string)方法会在我的情况下返回null

class Sandbox {

    const string listBoxName = "lb";

    [STAThread]
    static void Main(string[] args) {

        Window win = new Window();

        ListBox lb = new ListBox();
        lb.Name = listBoxName;

        win.Content = lb;
        win.IsVisibleChanged += Win_IsVisibleChanged;

        Application app = new Application();
        app.Run(win);
    }

    private static void Win_IsVisibleChanged(Object sender,
        DependencyPropertyChangedEventArgs e) {

        if ((bool)e.NewValue) {

            Window win = sender as Window;
            var lb = win.FindName(listBoxName); // null
            // ...
        }
    }
}

来自MSDN

  

如果元素具有子元素,则这些子元素都是   递归搜索请求的命名元素。

我的lbwin对象的子元素,但win.FindName(listBoxName)无法找到它...

1 个答案:

答案 0 :(得分:1)

您可以在MSDN文档中看到您链接的内容:

  

FindName在当前元素的名称范围内运行。

其中,名称范围是XAML名称范围。从XAML构建控件树时,将创建这些范围。当您自己构建树时,当根本不涉及XAML时(例如在您的情况下) - 默认情况下不会创建此类范围。这意味着在XAML范围内没有注册任何控件,因为根本没有这样的范围。您可以阅读有关XAML范围here的更多信息。

但是,如果您愿意,您可以自己创建范围并注册您的姓名:

class Program {
    const string listBoxName = "lb";

    [STAThread]
    static void Main(string[] args) {

        Window win = new Window();
        // create scope and associate it with Window
        NameScope.SetNameScope(win, new NameScope());
        ListBox lb = new ListBox();
        lb.Name = listBoxName;
        // register "lb" name
        win.RegisterName(listBoxName, lb);

        win.Content = lb;
        win.IsVisibleChanged += Win_IsVisibleChanged;

        Application app = new Application();
        app.Run(win);
    }

    private static void Win_IsVisibleChanged(Object sender,
        DependencyPropertyChangedEventArgs e) {

        if ((bool) e.NewValue) {

            Window win = sender as Window;
            var lb = win.FindName(listBoxName); // null
            Console.WriteLine(lb);
        }
    }
}