我最近一直在Silverlight工作,我慢慢发现,尽管开发起来很简单,但有一两个令人烦恼的陷阱潜伏在阴影中。
考虑到其中一些人为我追踪有多困难,我认为将其列在此处以供其他人受益可能是有用的。我确信我遇到的那些与其他人的经历相比毫无意义,我想尽量避免任何其他令人讨厌或耗时的惊喜。
那么,你有什么?
更新
我已经更新了这个以涵盖Silverlight。因此,请提供与响应时相关的版本或列表版本。对于那些没有版本的人,请假设Silverlight 2.0,因为原始问题就是这种情况。
答案 0 :(得分:13)
我所经历的两个是:
要使Silverlight使用托管在其他域上的Web服务,服务器需要a cross domain policy file。这可以采用两种格式:
我无法让前者正常工作,但后者工作(Flash使用第二个,而我相信第一个是特定于ASP虽然我无法让它在ASP.NET 2.0服务器下工作,所以它可能是3.5特定的。)
Silverlight 2.0组合框控件仅在首次显示时对其下拉区域进行一次调整。因此,它的大小基于列表中的初始项。这意味着即使列表增加到200,2个项目也会给你2个项目的高下拉列表。唯一的解决方法似乎是每次项目更改时用一个全新的控件替换组合。
请注意,将Height属性或MaxHeight属性设置为导致在下拉列表的初始显示中出现在列表中的项目的值将导致缺少垂直滚动条,因此无法访问项目你的清单。我发现的唯一解决方案是使用MinHeight属性至少具有适合所有用途的高度,如果物品超过最小高度则让它更大。
此外,当您调整浏览器窗口的大小时,无论您是否使用MinHeight,然后下拉组合列表或在可见时调整大小,这都会不可逆转地减小下拉列表的大小。
更新的Here is a really nice solution to the combo problem,感谢markti。
答案 1 :(得分:8)
Jeff Yates mentioned in his reply奇怪的一件事是ComboBoxes - 我亲眼看过一个,我也看到了另一个非常非常恼人的问题。如果您尝试从按钮的Click事件的事件处理程序更改ComboBox中的项目,您将收到一个我目前无法想到的神秘错误消息。我的解决方案是在Jeff的解决方案中做同样的事情 - 删除组合框,构建一个新的组合框,用更改的项目集填充它,然后将其添加回包含的面板。
Silverlight与WPF的ElementName绑定功能没有任何关系。 This post有一个很好的解决方法,对我来说效果很好。
捕获鼠标滚轮事件没有本机支持。 This post提供了一个使用浏览器事件的解决方案。
有一个Loaded事件,但没有Unloaded - 如果你想从屏幕上删除一个控件并运行一些卸载逻辑,你需要按照自己的方式这样做。我有一个IUnloadable接口,我从那个需要运行卸载逻辑并在时机成功时手动调用一个方法来获取我的控件。
最后,this post提供了一些关于Silverlight与WPF相比缺失的信息。
答案 2 :(得分:7)
缺少双击事件对我来说是一个。令我感到惊讶的是,它不在那里,并一直在intellisense列表中查找:-)通过在其上创建一个hack解决它,但这不是一个解决方案。
答案 3 :(得分:6)
我发现调试支持非常不稳定。它曾经为我工作过一段时间,但从那以后,无论我尝试什么。我认为它可能只有在使用Silverlight ASP支持通过ASP.NET 3.5站点调试时才能正常工作。
问题在于使用谷歌浏览器。由于Google Chrome在其自己的进程中托管Silverlight,因此调试器无法找到它。如果您使用IE7进行调试,它会很好地附加,但如果您使用Chrome进行调试,则必须先手动将其附加到Chrome下的相应Silverlight任务,然后才能运行。
感谢mattmanser for the clue问题可能是什么。
答案 4 :(得分:4)
短时间内有这么多不同版本的事实。
好 - 令人沮丧的事情很快得到解决。例如鼠标滚轮,右键单击 - 在Silverlight 4中修复。
错误 - 如果你是新手,你不知道是否仍然需要记录在案的'黑客'。我正在开始使用Silverlight 4并找到一大堆教程和帮助 - 但从来不知道它们是最新的还是最好的方法。
答案 5 :(得分:4)
HttpWebRespone只能有两个状态码之一
这意味着所有其他错误都映射到404,这非常烦人。我不知道重定向是如何工作的(我希望它们会被自动跟踪......)
http://msdn.microsoft.com/en-us/library/system.net.httpstatuscode(VS.95).aspx
答案 6 :(得分:4)
网络请求中没有可用的凭据
Credentials
或WebClient
无法使用HttpWebRequest
媒体资源。您需要通过proxy service that will do the credentials运行请求。
答案 7 :(得分:4)
使用IE6和托管Silverlight App的网站已启用压缩(HTTP 1.1标头)
每当您进行Web服务调用时,即使Fiddler显示正在发送的请求并且响应成功到达,它也会失败。
答案 8 :(得分:4)
最近得到我的是没有LayoutTransform属性(尽管有RenderTransform属性)。因此,您无法应用变换并使相邻元素遵循控件的“新空间要求”,这将导致它与其他元素重叠或具有空白。
这对我来说是个问题,因为我希望滚动查看器内的可滚动区域随变换而变化。我能够绕过它,但如果你试图旋转或进行另一次转换,这个过程会更加困难。
答案 9 :(得分:3)
哦有负载。让我们从3个浏览器陷阱开始:
除了IE之外的任何东西:Silverlight对象不会缩放以适应浏览器窗口。 解决方法:将其放在标记之间:
<style type="text/css">
html, body, form { height: 100% }
</style>
另请注意,IE将允许您在localhost中使用您的开发网站,并且您的应用访问其他域,而其他浏览器则不会。
Safari :如果您使用自定义响应标头(这对于在数据服务中执行高效分页非常有用),Safari可能会更改标题名称破坏您应用的情况。
可见性问题
更改折叠可见性组件的属性存在各种问题,通常情况是,当它们不可见时,它们不会注册更改,而当您使更改可见时,您必须再次执行更改。 SL团队似乎没有彻底测试当你使组件看不见和可见时会发生什么。
如果您遇到意外的间歇性ArgumentException,这可能是因为您在按钮的单击事件中有代码,这使得按钮本身(或其父元素)不可见。显然,一些内部代码在点击事件之后运行,该事件期望按钮可见。通过在click事件中创建一个简短的(例如100ms)DespatcherTimer来解决这个问题,并在Tick事件中将该按钮设置为不可见。
DependencyObject / DependencyProperty问题
如果您已经习惯了这些在WPF中工作的方式,那么它们在Silverlight中彻底破解了。如果您的数据对象是DependencyObjects,您将遇到2个问题。一个是在SL DependencyProperties中没有内置的更改通知 - 如果您希望它们更新绑定,您需要使对象实现INotifyPropertyChanged。另一个是如果你绑定到DependencyObjects的集合,你将获得非常奇怪的效果。您需要在控件层次结构中稍微使用一个类 - 我继承自FrameworkTemplate。所以我建议您的数据对象如下所示:
public class CustomDataObject : FrameworkTemplate, INotifyPropertyChanged
{ ... }
<强>转换器强>
没有多值转换器,也没有Binding.DoNothing。我所知道的没有解决方法。
答案 10 :(得分:3)
OpenFileDialog /隔离存储
为了让您的应用最初使用或增加本地存储空间,您必须指定所需的空间,然后Silverlight会提示用户是否允许更改。这一切都很好。但有一个问题:如果打开文件对话框,那么在此之后就无法获得更多存储空间。在我的场景中,用户选择了文件,我处理了它们,然后计算了保存处理文件所需的空间。但由于这个问题,我不得不猜测该文件的最大大小是什么,并根据它要求存储。如果文件较大,则用户必须重新进行整个过程。
布局系统
这真的很糟糕。在明确设置元素大小之前,您将获得所有大小属性的NaN。您可以挂钩到每个resize事件并获取值,但在大多数情况下,您不能只询问高度或宽度并得到您想要的。
没有LayoutTransform
特拉维斯提到above
答案 11 :(得分:3)
前段时间我在Silverlight 2.0中做了一个项目,该项目是使用TDD和MVP驱动的。我的服务引用位于单独的程序集中,因此视图不需要知道模型。我有一个关于 ServiceReferences.ClientConfig 文件位置的问题,该文件需要在视图的程序集中!
如果添加服务引用,则会生成此文件。我们添加了一个WCF Web服务,但我是Silverlight的新手,因此不知道Silverlight应用程序是作为XAP编译和打包的。
如果 ServiceReferences.ClientConfig 文件不在此XAP中,则表示您遇到问题。
所以我的两分钱值得。我在Silverlight论坛上发布了一段时间,似乎我并不是唯一一个应用这个问题的人。
答案 12 :(得分:2)
调试可能很棘手,如果它不起作用,可能是因为你在进程上附加了错误的代码类型。尝试手动附加到流程并确保选择“silverlight代码”而不是“托管代码”。从那以后它可能会一直有效。
答案 13 :(得分:2)
我最近正在使用System.Windows.MessageBox
静态类(目前,这是获取应用程序模式的唯一方法 - 而不仅仅是UI模式 - 用户反馈)我发现了消息框的烦人焦点处理将焦点返回到浏览器,而不是在显示消息框之前具有焦点的Silverlight控件。毫无疑问,由于使用浏览器显示消息框的Silverlight插件,但它令人恼火,并且结合可用于自定义消息框的有限选项,很快我很明显需要用其他东西来提供我的用户反馈。
在搜索互联网之后,很明显我需要使用某种基于Popup
原语的用户界面模态显示。所以,我推出了自己的模态对话框类,我发现了另一个问题。
弹出窗口下方的用户界面仍处于活动状态,这意味着使用标签可以访问您尝试隐藏的控件。为了缓解这种情况,我首先尝试通过获取RootVisual
(即页面)并将IsEnabled
设置为false
来禁用该页面。这很有效,直到我在DataGrid
编辑操作期间使用了我的对话框。对话框代码工作了两次,再也没有。似乎在编辑期间禁用和启用网格会在Silverlight中导致某种不可恢复的问题(可能是内存泄漏,因为它最终崩溃)。
事实证明,要实现我想要的目标,最简单的方法是在我的弹出对话框中将焦点设置为某个内容,并将TabNavigation
属性设置为KeyboardNavigationMode.Cycle
。这样,焦点永远不会离开对话框,因此底层UI仍然不受限制,但不会产生上述问题。
答案 14 :(得分:1)
不支持模态弹出窗口 解决方案 - 创建一个用户控件,用于扩展整个画布并将不透明度设置为.05 正如ScottGu的Silverlight应用程序示例所示 http://weblogs.asp.net/scottgu/pages/silverlight-2-end-to-end-tutorial-building-a-digg-search-client.aspx
不支持数据集 解决方案 - 使用LINQ to XML将XML读入通用列表以进行数据绑定目的
不支持母版页 解决方案 - 创建父XAML页面,并使用用户控件创建应用程序的其余部分,以便您可以在它们之间切换
将AJAX工具包与ASP.NET Silverlight标记一起使用时会出现名称空间问题 解决方案 - 使用OBJECT标记而不是ASP.NET Silverlight标记。
答案 15 :(得分:0)
令人沮丧的是,Silverlight在调试时会吞下这么多异常。
答案 16 :(得分:0)
在资源中声明一个控件,然后尝试将其设置为Popup
,这将导致一个异常,表明该控件已经有一个父控件。在这种情况下,无法检测父项是什么并将其删除(我尝试了许多不同的方法)。解决方法是将我的控件包装在资源的弹出窗口中,然后让我的代码重新使用该弹出窗口,或者通过重新创建控件将其丢弃以支持我自己的代码。由于控件可以将弹出窗口标识为其父级,因此这很容易做到。