简体   繁体   English

找不到应该存在的元素?

[英]Can't find element that should exist?

I am adding tabs to my tab control through code: 我通过代码向我的标签控件添加标签:

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

As you can see, it creates the header of the tabItem with a stack panel. 如您所见,它使用堆栈面板创建tabItem的标题。 It adds two text blocks; 它添加了两个文本块; one of which is empty, but I've assigned the name "extra". 其中一个是空的,但我已将名称指定为“ extra”。 What I would like to do is, later in the code, edit the textBlock named "extra" and add some new text to it. 我想做的是,在代码的后面,编辑名为“ extra”的textBlock并向其中添加一些新文本。

How would I find and edit this element? 我将如何查找和编辑此元素? I have tried the following code, but its producing an error saying the element can not be found: 我尝试了以下代码,但产生错误,提示找不到该元素:

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

FindName is what you are looking for but your TextBlock is not in the correct WPF Namescope. FindName是您要查找的内容,但您的TextBlock不在正确的WPF Namescope中。

MSDN states : MSDN指出

If you add an object to an object tree at a point in time after the XAML that produced that tree was parsed, a Name or x:Name value on the new object does not automatically update the information in a XAML namescope. 如果在解析生成该树的XAML之后的某个时间点将对象添加到对象树中,则新对象上的Name或x:Name值不会自动更新XAML namescope中的信息。 To add a name for an object into a WPF XAML namescope after XAML is loaded, must call the appropriate implementation of RegisterName on the object that defines the XAML namescope. 若要在XAML加载后将对象的名称添加到WPF XAML名称范围,必须在定义XAML名称范围的对象上调用RegisterName的适当实现。

For example: 例如:

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

...

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

Finally, Application.Current.FindResource("extra") is returning null because the element does not exist when project resources are created. 最后, Application.Current.FindResource("extra")返回null,因为在创建项目资源时该元素不存在。 More on FindResource. 有关FindResource的更多信息。

Just use FrameworkElement.FindName method: 只需使用FrameworkElement.FindName方法:

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

You don't need Application.Current.Resource dictionary here because it's different collection. 您不需要Application.Current.Resource字典,因为它是不同的集合。 If you want to use it then you should put user controls within Resource dictionary beforehand. 如果要使用它,则应事先将用户控件放在资源字典中。

Because you are trying to find resource with the key "extra". 因为您正在尝试使用键“ extra”查找资源。 It's wrong. 这是不对的。

Try this: 尝试这个:

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

Now you can reach it with textBlock instance. 现在,您可以使用textBlock实例到达它。

Here's some VB WPF code for what you need 这是一些您需要的VB WPF代码

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

I have no idea if it will work like that in C# WPF although if that doesn't work try looking up CType 我不知道它是否会像在C#WPF中那样工作,尽管如果这样不起作用,请尝试查找CType

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM