简体   繁体   中英

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. It adds two text blocks; one of which is empty, but I've assigned the name "extra". What I would like to do is, later in the code, edit the textBlock named "extra" and add some new text to it.

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.

MSDN states :

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. 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.

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. More on FindResource.

Just use FrameworkElement.FindName method:

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. 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". 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.

Here's some VB WPF code for what you need

    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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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