2011-10-05 76 views
4

我遇到了一个问题,我正在使用FrameworkElement对象的“FindName()”方法来搜索该元素的子控件。Silverlight:FrameworkElement.FindName()在浏览器窗口中不可见时找不到控件

有一些有趣的行为,我注意到,似乎无法弄清楚。 如果用户滚动浏览器窗口,以便在窗口框架的上下文中不再显示控件本身,则“FindName()”不会返回该元素。 但是,如果该控件在窗口框架中可见,它会发现它很好。

这是一个已知的问题?有没有其他人遇到过这个?

我不是在谈论控件的可见性属性。 Visibility属性设置为Visible。

更新 我试图在ListBox控件设置VirtualizingStackPanel.VirtualizationMode =“标准”(这是我在寻找的容器),它仍然没有找到指定的控制。

+1

是您的虚拟化容器的命名控件? – Denis

+0

包含我正在查找的控件的控件是一个ListBox。我相信我只是发现默认情况下,UI虚拟化对于ListBox而言是有效的,这很可能是问题所在。如何关闭特定控件的UI虚拟化? 要在ListBox控件本身上尝试VirtualizingStackPanel.VirtualizationMode =“Standard”。将回报。 –

回答

2

如果您使用的工具如Silverlight Spy您可以尝试手动找到控件。

如果它不在那里它可能在a virtualizing stackpanel

+0

这确实是UI虚拟化的问题。谢谢。 http://stackoverflow.com/questions/7680459/silverlight-disable-ui-virtualization –

3

如果我正确理解你的意思,你说当一个控件滚出应用程序的ViewPort时,即使它的可见属性保持为真,FrameworkElement.FindName(“”)也找不到它。

我想你已经通过所有的基础工作重新:XAML中划定范围等,如果您要添加控件动态你确定你从如果是正确的父元素等走:

使用RedGates反射器我们可以看到如下的是FrameWorkElement.FindName实现:

public object FindName(string name) 
{ 
    return XcpImports.DependencyObject_FindName(this, name); 
} 

XcpImports.DependencyObject_FindName实现为

[SecuritySafeCritical] 
internal static DependencyObject DependencyObject_FindName(DependencyObject referenceDO, string name) 
{ 
    int num; 
    IntPtr ptr; 
    CheckThread(); 
    if (name == null) 
    { 
     throw new ArgumentNullException("name"); 
    } 
    uint hr = FindNameNative(JoltHelper.Context, (uint) name.Length, name, referenceDO.NativeObject, out num, out ptr); 
    GC.KeepAlive(referenceDO); 
    if ((hr != 0) && (hr != 0x80004005)) 
    { 
     throw Error.MarshalXresultAsException(hr); 
    } 
    return (DependencyObject) ConvertDO(ptr, num, true); 
} 

所以,除非你遇到一个例外,我觉得最有趣的线大概是:

uint hr = FindNameNative(JoltHelper.Context, (uint) name.Length, name, referenceDO.NativeObject, out num, out ptr); 

这是跨入本机代码,并确定通过在XcpImports一个DLL导入:

[DllImport("agcore", EntryPoint="FindName", CharSet=CharSet.Unicode)] 
private static extern uint FindNameNative(IntPtr context, uint cString, [MarshalAs(UnmanagedType.LPWStr)] string name, IntPtr referenceObject, out int typeIndex, out IntPtr obj); 

为了不被与Developers Express的AgCore相混淆。

本文就ZDNET(大约2007年)由Ed伯内特:

http://www.zdnet.com/blog/burnette/dissecting-silverlight/297

说的是:

agcore.dll(安装2.2M) - 这是核心ActiveX控件是 负责Silverlight渲染和事件,包括音频和视频解码。

它还说低于指出:

npctrl.dll(460K) - 一种用于agcore包装。这使得它运行在Firefox内部 。

所以我的第一个问题是。你的问题在每个浏览器中是否一致? 也许它是在某些浏览器/版本中是agcore.dll的包装问题,而不是核心技术(agcore.dll)本身。

+0

我实际上是在IE中测试。在Chrome中也是如此。没有异常抛出,它根本找不到控制。 –

+0

O.k.所以在这种情况下,我会切换并重新检查问题:范围等。这可能是一个“真正的”错误,但如果它只是在游戏的最后阶段才被发现,我会感到惊讶。尝试这篇文章的方法来检查你的视觉树,特别是在接受的答案中有一个提到的Wpf Snoop工具的破解(希望它可以拾取Silverlight应用程序,如果不是,也尝试用浏览器)。 http://stackoverflow.com/questions/636383/wpf-ways-to-find-controls – rism

+0

我会回到绘图板,但再次重申,我正在逐步通过代码在断点之前“FindName()”调用,并且在控件滚动出视图的那个简单变化的情况下,找不到控件。 –