WPF - FindName不应该返回null

Vac*_*ano 33 c# wpf findname

FindName对我来说是坏的:(

如果你是这方面的专家,我会很乐意帮助你.

我正在寻找的对象就在那里.我有证据.

这是场景:

ToggleButton button = (ToggleButton)sender;
Popup popup = (Popup)button.FindName("popSelectIteration");
Run Code Online (Sandbox Code Playgroud)

popup是null但不总是.只是有时候.但即使它被设置为null,我正在寻找的孩子也在那里.

当它为null时我给了一个断点并抓住了这两个截图.

FindName为"popSelectIteration"返回null的位置:

alt text http://img175.imageshack.us/img175/2055/popupisnull.png

但如果你深入了解手表,就会发现孩子在那里:

替代文字http://img708.imageshack.us/img708/8757/watchwithpopupnull.png

那我错过了什么?为什么FindName找不到它?从屏幕截图中可以看出,这不是计时问题(FindName监视为空但直接路径很好).

有没有更好的方法来找到一个控件?

旁注:如果您在XAML中对有问题的切换按钮感兴趣,可以在这个问题中找到它:WPF - FrameworkElement - 枚举所有后代?.


更新:我做了一些挖掘,看看为什么这会失败一段时间,有时却失败了.我有一个调用的动画NameScope.SetNameScope((DependencyObject)form, new NameScope());(这里是完整的方法代码).在该调用之后,FindName开始失败.

我真的不明白这个电话.我想我复制并粘贴了代码.无论如何,我评论了它.但我很想知道为什么会失败.

Pat*_*lug 37

我猜它与视觉和逻辑树之间的区别有关.控件位于逻辑树中,但可能尚未应用此控件的模板,因此FindName不会返回任何有用的内容.

你可以尝试调用ApplyTemplate(); 首先在容器上.

这也可以解释为什么它有时会返回一些东西.

  • 为我工作。Template.FindName() 有这个问题 (2认同)
  • 这对我有用,对于最初隐藏的控件或最初不可见的选项卡上的控件来说,这是一个更多的问题。 (2认同)

Shr*_*ike 34

尝试

LogicalTreeHelper.FindLogicalNode(button, "popSelectIteration");
Run Code Online (Sandbox Code Playgroud)


Gh6*_*h61 13

聚会有点晚了(实际上并没有回答OP问题),但是

当您动态添加元素时,它们无法被FindName. 您需要通过调用 来注册它们RegisterName

例子:

string number = GenerateNumber();

Button myButton = new Button();
myButton.Content = number;
myButton.Name = "button_" + number;

RegisterName(myButton.Name, myButton);

Panel.Children.Add(myButton);
object o = Panel.FindName(myButton.Name);
Run Code Online (Sandbox Code Playgroud)

也许有人会发现这很有用。


小智 6

根据我的经验,当您通过代码隐藏添加项目时会发生这种情况.我发现你可以FindName()通过名称范围欺骗(或动画框架).也就是说,当你创建控件时,就可以了

    NameScope.GetNameScope(yourContainer).RegisterName("name of your control", yourControlInstance);
Run Code Online (Sandbox Code Playgroud)

但是,要使其可靠地工作,您必须确保取消注册名称:

    NameScope.GetNameScope(yourContainer).UnregisterName("name of your control");
Run Code Online (Sandbox Code Playgroud)

发布此信息以供将来参考.