为什么我不能通过Name使用FindName()访问TextBox?

时间:2009-11-18 11:29:12

标签: c# wpf xaml textbox

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

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>

代码背后:

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);
        }
    }
}

答复补遗:

非常感谢,布鲁诺,效果很好。为了不两次添加相同的名称,我用它包装:

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

或者,如果您要注册除TextBox之外的任何内容,则为通用版本:

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

1 个答案:

答案 0 :(得分:15)

这与WPF XAML Namescopes

有关

因为您向已解析的元素树添加元素,所以需要调用RegisterName

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

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

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

     

元素树的任何添加   初始加载和处理后   必须打电话给相应的   RegisterName的实现   定义XAML名称范围的类。   否则,添加的对象不能   通过方法引用名称   比如FindName。仅仅设置一个   名称属性(或x:名称属性)   不会将该名称注册到任何名称中   XAML名称范围。添加命名元素   到具有XAML的元素树   namescope也没有注册   XAML名称范围的名称。虽然   您可以嵌套XAML名称范围   通常将名称注册到XAML   根目录上存在的名称范围   元素,以便您的XAML名称范围   位置与XAML名称范围平行   本来应该创建的   等效加载的XAML页面。最多   应用程序的常见场景   开发人员就是你要用的   RegisterName将名称注册到   当前根目录下的XAML名称范围   的页面。 RegisterName是其中的一部分   寻找的一个重要方案   故事板将运行为   动画。有关更多信息,请参阅   故事板概述。如果你打电话   RegisterName在除以外的元素上   同一对象中的根元素   树,名称仍然注册   最接近根的元素,好像   你在上面调用了RegisterName   根元素。