为什么我不能使用 FindName() 按名称访问 TextBox? [英] Why can't I access a TextBox by Name with FindName()?

查看:34
本文介绍了为什么我不能使用 FindName() 按名称访问 TextBox?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 FindName() 在以下示例中返回 null?

XAML:

<堆栈面板><边界><DockPanel x:Name="FormBase" LastChildFill="True"></DockPanel></边界><按钮内容="保存" Click="Button_Click"/></堆栈面板></窗口>

代码隐藏:

使用系统;使用 System.Windows;使用 System.Windows.Controls;命名空间 TestDynamicTextBox343{公共部分类 Window1:窗口{公共窗口1(){初始化组件();StackPanel sp = new StackPanel();sp.Orientation = 方向.水平;文本块 textBlock = new TextBlock();textBlock.Text = "名字:";文本框 textBox = new TextBox();textBox.Name = "名字";textBox.Text = "测试";sp.Children.Add(textBlock);sp.Children.Add(文本框);FormBase.Children.Add(sp);}私人无效Button_Click(对象发送者,RoutedEventArgs e){文本框 tb = (TextBox)this.FindName("FirstName");Console.WriteLine(tb.Text);}}}

答案附录:

非常感谢,布鲁诺,效果很好.为了不重复添加相同的名称,我用这个包装它:

void RegisterTextBox(string textBoxName, TextBox textBox){if ((TextBox)this.FindName(textBoxName) != null)this.UnregisterName(textBoxName);this.RegisterName(textBoxName, textBox);}

或者,如果您将注册除 TextBoxes 以外的任何内容,则为通用版本:

void RegisterControl(string textBoxName, T textBox){如果 ((T)this.FindName(textBoxName) != null)this.UnregisterName(textBoxName);this.RegisterName(textBoxName, textBox);}

解决方案

这个和WPF XAML 名称范围.

因为你将元素添加到解析的元素树,你需要调用 RegisterName.

<代码> ...文本框 textBox = new TextBox();textBox.Name = "名字";textBox.Text = "测试";this.RegisterName("FirstName", textBox);...

<块引用>

向解析的元素添加元素树木

对元素树的任何添加初始加载和处理后必须调用适当的RegisterName 的实现定义 XAML 名称范围的类.否则,添加的对象不能通过方法按名称引用例如查找名称.仅仅设置一个名称属性(或 x:Name 属性)不会将该名称注册到任何XAML 名称范围.添加命名元素到具有 XAML 的元素树namescope 也没有注册名称到 XAML 名称范围.虽然XAML 名称范围可以嵌套,你通常将名称注册到 XAML存在于根目录的名称范围元素,以便您的 XAML 名称范围位置与 XAML 名称范围平行这将在一个等效加载的 XAML 页面.最多应用的常见场景开发人员是您将使用的RegisterName 将名称注册到当前根目录上的 XAML 名称范围的页面.注册名称是寻找的一个重要场景故事板将作为动画.有关详细信息,请参阅故事板概述.如果你打电话RegisterName 以外的元素同一对象中的根元素树,名称仍然注册到最接近根的元素,好像你曾在根元素.

Why does FindName() return null in the following example?

XAML:

<Window x:Class="TestDynamicTextBox343.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <Border >

            <DockPanel x:Name="FormBase" LastChildFill="True">

            </DockPanel>

        </Border>

        <Button Content="Save" Click="Button_Click"/>
    </StackPanel>
</Window>

Code Behind:

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

namespace TestDynamicTextBox343
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();


            StackPanel sp = new StackPanel();
            sp.Orientation = Orientation.Horizontal;

            TextBlock textBlock = new TextBlock();
            textBlock.Text = "First Name: ";

            TextBox textBox = new TextBox();
            textBox.Name = "FirstName";
            textBox.Text = "test";

            sp.Children.Add(textBlock);
            sp.Children.Add(textBox);
            FormBase.Children.Add(sp);

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            TextBox tb = (TextBox)this.FindName("FirstName");
            Console.WriteLine(tb.Text);
        }
    }
}

Addendum to Answer:

Thanks a lot, Bruno, that worked well. In order not to add the same name twice, I wrap it with this:

void RegisterTextBox(string textBoxName, TextBox textBox)
{
    if ((TextBox)this.FindName(textBoxName) != null)
        this.UnregisterName(textBoxName);
    this.RegisterName(textBoxName, textBox);
}

Or if you will be registering anything other than TextBoxes, a generic version:

void RegisterControl<T>(string textBoxName, T textBox)
{
    if ((T)this.FindName(textBoxName) != null)
        this.UnregisterName(textBoxName);
    this.RegisterName(textBoxName, textBox);
}

解决方案

This is related to WPF XAML Namescopes.

Because you add elements to parsed element trees, you need to call RegisterName.

        ...
        TextBox textBox = new TextBox();
        textBox.Name = "FirstName";
        textBox.Text = "test";

        this.RegisterName("FirstName", textBox);
        ...

Adding Elements to Parsed Element Trees

Any additions to the element tree after initial loading and processing must call the appropriate implementation of RegisterName for the class that defines the XAML namescope. Otherwise, the added object cannot be referenced by name through methods such as FindName. Merely setting a Name property (or x:Name Attribute) does not register that name into any XAML namescope. Adding a named element to an element tree that has a XAML namescope also does not register the name to the XAML namescope. Although XAML namescopes can be nested, you generally register names to the XAML namescope that exists on the root element, so that your XAML namescope location parallels the XAML namescope that would have been created in an equivalent loaded XAML page. The most common scenario for application developers is that you will use RegisterName to register names into the XAML namescope on the current root of the page. RegisterName is part of one important scenario for finding storyboards that will run as animations. For more information, see Storyboards Overview. If you call RegisterName on an element other than the root element in the same object tree, the name is still registered to the element nearest the root, as if you had called RegisterName on the root element.

这篇关于为什么我不能使用 FindName() 按名称访问 TextBox?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆