2014-10-03 2 views
1

Я добавляю вкладки в моих вкладках с помощью кода:Не удается найти элемент, который должен существовать?

TabItem tab = new TabItem(); 

var stack = new StackPanel() { Orientation = Orientation.Horizontal }; 
stack.Children.Add(new TextBlock() { Text = header }); 
stack.Children.Add(new TextBlock() { Name = "extra" }); 
tab.Header = stack; 

tabControl.Items.Add(tab); 

Как вы можете видеть, он создает заголовок TabItem с панелью стеки. Он добавляет два текстовых блока; один из которых пуст, но я присвоил имя «extra». Я хотел бы сделать это, позже в коде, отредактировать textBlock с именем «extra» и добавить к нему новый текст.

Как бы мне найти и отредактировать этот элемент? Я попытался следующий код, но его получения ошибку, сказав, что элемент не может быть найден:

object test = Application.Current.FindResource("extra"); 
+0

Во-первых, 'tabControl', вероятно, не является [ресурсом] (http://msdn.microsoft.com/en-us/library/system.windows.application.resources (v = vs.110) .aspx), но [Свойство] (http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx). Почему бы не получить доступ к нему через 'get'? –

+0

Почему это имеет значение? –

ответ

1

FindName - это то, что вы ищете, но ваш TextBlock не находится в правильном пространстве имен WPF.

MSDN states:

При добавлении объекта в дереве объектов в определенный момент времени после того, XAML, который произвел, что дерево разбирается, имя или х: Name значение на новом объекте автоматически не обновите информацию в проспекте XAML. Чтобы добавить имя объекта в пространство имен WPF XAML после загрузки XAML, необходимо вызвать соответствующую реализацию RegisterName для объекта, который определяет XAML namescope.

Например:

var textBlock = new TextBlock() { Name = "extra" }; 
stack.Children.Add(textBlock); 
RegisterName(textBlock); 

... 

TextBlock textBlock = FindName("extra") as TextBlock; 

Наконец, Application.Current.FindResource("extra") возвращается нуль, потому что элемент не существует, когда создаются ресурсы проекта. More on FindResource.

-2

Вот некоторые VB WPF код для того, что вам нужно

Dim test As TextBlock 
    test = DirectCast(FindName("extra"), TextBlock) 

Я понятия не имею, если это будет работайте так, как в C# WPF, хотя, если это не работает, попробуйте поискать CType

-1

Потому что вы пытаетесь найти ресурс с ключом «extra». Это не правильно.

Попробуйте это:

TabItem tab = new TabItem(); 

var stack = new StackPanel() { Orientation = Orientation.Horizontal }; 
var textBlock = new TextBlock() { Name = "extra" } 
stack.Children.Add(new TextBlock() { Text = header }); 
stack.Children.Add(textBlock); 
tab.Header = stack; 

tabControl.Items.Add(tab); 

Теперь вы можете достичь его с экземпляром TextBlock.

+0

Точно так же, как мой код ... –

+0

Не то же самое. Нет необходимости обращаться к XAML из кода, потому что вы добавляете элементы в codebehind. У вас уже есть экземпляры и вы можете их использовать. Просто назначил их переменной. –

0

Просто используйте FrameworkElement.FindName метод:

var control = tab.FindName("extra"); 
if(control is TextBlock){ 
    // your logic here 
} 

Вам не нужно Application.Current.Resource словарь здесь, потому что это разные коллекции. Если вы хотите использовать его, вы должны заранее поставить пользовательские элементы управления в словарь ресурсов.

+0

Вы предполагаете, что у меня есть доступ к вкладке. Код выполняется в пользовательском элементе управления. TabItem строится в MainWindow.У меня есть доступ к tabControl, но не самому tabItem. –

+0

На самом деле в главном окне также есть FindName, а «дополнительное» имя должно быть уникальным для окна. Попробуйте mainWindow.FindName («extra») вместо tab.FindName («extra») – Blablablaster

+0

Нет ... все еще не работает. Никогда не находит элемент. –

Смежные вопросы