Почему я не могу получить доступ к TextBox по имени с помощью FindName ()? - PullRequest
6 голосов
/ 18 ноября 2009

Почему 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);
}

1 Ответ

15 голосов
/ 18 ноября 2009

Это относится к 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 на корневой элемент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...