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(); 首先在容器上.
这也可以解释为什么它有时会返回一些东西.
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)
发布此信息以供将来参考.