【问题标题】:Why can't I access a TextBox by Name with FindName()?为什么我不能使用 FindName() 按名称访问文本框?
【发布时间】:2009-11-18 11:29:12
【问题描述】:

为什么 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);
}

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

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

【问题讨论】:

    标签: c# wpf xaml textbox


    【解决方案1】:

    这与WPF XAML Namescopes有关。

    因为你在解析后的元素树中添加元素,所以需要调用RegisterName

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

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

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

    【讨论】:

    • 我不知道是否应该使用 FindName() 函数注册所有我想查找的名称。我应该吗?
    • @LorenzoSciuto 只有那些你需要的,特别是那些将被动画定位的。
    猜你喜欢
    • 2020-01-11
    • 2016-08-14
    • 2016-11-25
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    相关资源
    最近更新 更多