FindName对我来说是破碎的:(
如果你是这方面的专家,我会很乐意帮助你。
我正在寻找的对象就在那里。我有证据。
以下是该方案:
ToggleButton button = (ToggleButton)sender;
Popup popup = (Popup)button.FindName("popSelectIteration");
popup
为空,但并非总是如此。只是有时候。但即使它被设置为null,我正在寻找的孩子就在那里。
我在它为空时设置了一个断点并抓住了这两个截图。
FindName为“popSelectIteration”返回null的位置:
alt text http://img175.imageshack.us/img175/2055/popupisnull.png
但如果你深入了解手表,就会看到孩子在那里:
alt text http://img708.imageshack.us/img708/8757/watchwithpopupnull.png
那我错过了什么?为什么FindName找不到它?从屏幕截图中可以看出,这不是计时问题(FindName监视为空,但直接路径很好)。
有没有更好的方法来找到控件?
旁注:如果您在XAML中对有问题的切换按钮感兴趣,可以在此问题中找到它:WPF - FrameworkElement - Enumerate all decendents?。
更新:我做了一些挖掘,看看为什么这会失败一次,有时却失败了。我有一个调用NameScope.SetNameScope((DependencyObject)form, new NameScope());
的动画(完整方法代码here)。在调用之后,FindName开始失败。
我真的不明白这个电话。我想我复制并粘贴了代码。无论如何,我评论了它。但我很想知道为什么会失败。
答案 0 :(得分:34)
我猜它与视觉树和逻辑树之间的区别有关。控件位于逻辑树中,但可能尚未应用此控件的模板,因此FindName不会返回任何有用的内容。
您可以尝试调用ApplyTemplate();首先在容器上。
这也可以解释为什么它有时会返回一些东西。
答案 1 :(得分:32)
尝试
LogicalTreeHelper.FindLogicalNode(button, "popSelectIteration");
答案 2 :(得分:6)
根据我的经验,当您通过代码隐藏添加项目时会发生这种情况。我发现你可以通过名称范围欺骗FindName()
(或动画框架)。也就是说,当你创建控件时,你可以
NameScope.GetNameScope(yourContainer).RegisterName("name of your control", yourControlInstance);
为了使其可靠地工作,您必须确保取消注册名称:
NameScope.GetNameScope(yourContainer).UnregisterName("name of your control");
发布此信息以供将来参考。
答案 3 :(得分:2)
我现在遇到了同样的问题,但我使用的方法如下:
#region Override - OnApplyTemplate
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.PART_ListViewLeft = GetTemplateChild(cPART_ListViewLeft) as ListView;
this.PART_ListViewCenter = GetTemplateChild(cPART_ListViewCenter) as ListView;
this.PART_ListViewRight = GetTemplateChild(cPART_ListViewRight) as ListView;
this.PART_GridViewLeft = GetTemplateChild(cPART_GridViewLeft) as DsxGridView;
this.PART_GridViewCenter = GetTemplateChild(cPART_GridViewCenter) as DsxGridView;
this.PART_GridViewRight = GetTemplateChild(cPART_GridViewRight) as DsxGridView;
if(this.PART_ListViewLeft!=null)
this.PART_ListViewLeft .AlternationCount = this.AlternatingRowBrushes.Count;
if(this.PART_ListViewCenter!=null)
this.PART_ListViewCenter .AlternationCount = this.AlternatingRowBrushes.Count;
if(this.PART_ListViewRight!=null)
this.PART_ListViewRight .AlternationCount = this.AlternatingRowBrushes.Count;
// ApplyTempleted = true;
CreateColumnLayout();
}
#endregion
如果控件是动态创建的,并且“可见性”设置为隐藏或折叠的容器或其容器,则代码“this.PART_ListViewLeft = GetTemplateChild(cPART_ListViewLeft)”为ListView;“将始终返回null,原因很明显:在调用OnApplyTemplate之前尚未应用datatemplete !!!!!!! 所以你的问题应该是同一个!! 祝你好运!
答案 4 :(得分:1)
我建议根据我的经验避免使用FindName函数,当您尝试在DataTemplate中找到应用于某些控件的内容时,尤其有问题。 相反,如果可能(基于您的软件架构)在XAML中声明Popup 像资源一样引用它或使用Binding将一些Model属性设置为它的引用。 祝你好运。
答案 5 :(得分:0)
ellipseStoryboard.Children.Add(myRectAnimation); containerCanvas.Children.Add(myPath); 添加后,注册控件 RegisterName(“ TextBlock1”,Var_TextBox); 要么 RegisterName(myRectAnimation.Name,myRectAnimation); RegisterName(myPath.Name,myPath);
答案 6 :(得分:0)
聚会晚一点(实际上并没有回答OP问题),但是
动态添加元素时,FindName
无法找到它们。
您需要通过致电RegisterName
进行注册。
示例:
Button myButton = new Button();
myButton.Content = generateNumber();
myButton.Name = "button_" + generateNumber;
RegisterName(myButton.Name, myButton);
Panel.Children.Add(myButton);
object o = Panel.FindName(myButton.Name);
也许有人会觉得有用。
答案 7 :(得分:-1)
尝试使用button.FindResource("popSelectIteration")