在 DataTemplate 中使用(不受支持的)事件处理程序时没有警告或错误
No warning or error when using (unsupported) event handler inside DataTemplate
场景
在 Silverlight 应用程序的视图中考虑以下 XAML:
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" MouseLeftButtonDown="Item_Clicked" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
未调用事件处理程序。显然,事件处理程序在 DataTemplate
中不起作用。
在编译时和运行时都没有警告或错误。此外,MSDN DataTemplate reference 未指定有关事件处理程序的任何限制。
IntelliSense 甚至 "helps" 我 <New Event Handler>
和 Navigate to Event Handler
。处理程序放在视图的代码后面。
问题
- 微软规定的行为吗?
- 这是 VS2010 中的已知错误吗?
- 为什么编译器不发出错误或
至少一个警告?
备注
我知道如何解决这个问题,因为这个问题在这个网站上经常被报告。我想知道为什么这会默默地失败。
"Silent error" 在编写 .NET 代码时永远不会让您走得太远,错误永远不会消失。我将描述解决此类问题的一般方法,让您自动进入 "why" 并让您有机会 google 解决方案。
您需要了解的一个重要实现细节是构建应用程序时如何处理 XAML。它由代码生成器解释,它自动生成存储在项目的 obj\Debug
目录中的 C# 代码。构建后,您会在那里找到 *.g.cs
个文件。看看它们,理解它们应该不难,从标记自动生成的代码用 #line
指令注释。
查看 Silverlight 版本,MainPage.g.cs,显示很少的代码(已编辑以适合):
public partial class MainPage : System.Windows.Controls.UserControl {
internal System.Windows.Controls.Grid LayoutRoot;
private bool _contentLoaded;
public void InitializeComponent() {
// etc..
}
}
在任何地方都没有出现 MouseLeftButtonDown 事件的迹象,这当然不令人鼓舞。
使用示例 WPF 应用执行完全相同的操作。现在看看 MainWindow.g.cs(再次编辑以适应和删除无聊的部分):
public partial class MainWindow : System.Windows.Window,
System.Windows.Markup.IComponentConnector,
System.Windows.Markup.IStyleConnector {
private bool _contentLoaded;
public void InitializeComponent() {
//...
}
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
//...
}
void System.Windows.Markup.IStyleConnector.Connect(int connectionId, object target) {
switch (connectionId)
{
case 1:
#line 9 "..\..\MainWindow.xaml"
((System.Windows.Controls.TextBlock)(target)).MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(this.Item_Clicked);
//...
break;
}
}
大不同,现在您做 看到 MouseLeftButtonDown 事件回来了。显然,IStyleConnector
界面有助于订阅该事件。
所以去看看那个界面的MSDN article。相当简短,这是你不应该知道的内部管道,描述是:
Provides methods used internally by the WPF XAML parser to attach events and event setters in compiled XAML.
当然,与您要完成的目标完全匹配。该文章中最重要的是版本信息部分。在 .NET Framework 中受支持,但 Silverlight 未 列出。
这为您提供了 "why",必要的管道在 Silverlight 中根本不可用。否则不足为奇,Silverlight 最重要的属性是它 小 ,允许快速下载,当用户浏览到使用的网页时不会减慢用户的速度它。它只能通过删除东西来变小。
所以,显然你应该自己提供管道。你怎么做到这一点?受启发的 google 查询是 silverlight datatemplate event. The very first hit is a winner, a question,它试图完全 您正在做的事情。如果您需要更多帮助,可以使用更多相关匹配项。
场景
在 Silverlight 应用程序的视图中考虑以下 XAML:
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" MouseLeftButtonDown="Item_Clicked" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
未调用事件处理程序。显然,事件处理程序在 DataTemplate
中不起作用。
在编译时和运行时都没有警告或错误。此外,MSDN DataTemplate reference 未指定有关事件处理程序的任何限制。
IntelliSense 甚至 "helps" 我 <New Event Handler>
和 Navigate to Event Handler
。处理程序放在视图的代码后面。
问题
- 微软规定的行为吗?
- 这是 VS2010 中的已知错误吗?
- 为什么编译器不发出错误或 至少一个警告?
备注
我知道如何解决这个问题,因为这个问题在这个网站上经常被报告。我想知道为什么这会默默地失败。
"Silent error" 在编写 .NET 代码时永远不会让您走得太远,错误永远不会消失。我将描述解决此类问题的一般方法,让您自动进入 "why" 并让您有机会 google 解决方案。
您需要了解的一个重要实现细节是构建应用程序时如何处理 XAML。它由代码生成器解释,它自动生成存储在项目的 obj\Debug
目录中的 C# 代码。构建后,您会在那里找到 *.g.cs
个文件。看看它们,理解它们应该不难,从标记自动生成的代码用 #line
指令注释。
查看 Silverlight 版本,MainPage.g.cs,显示很少的代码(已编辑以适合):
public partial class MainPage : System.Windows.Controls.UserControl {
internal System.Windows.Controls.Grid LayoutRoot;
private bool _contentLoaded;
public void InitializeComponent() {
// etc..
}
}
在任何地方都没有出现 MouseLeftButtonDown 事件的迹象,这当然不令人鼓舞。
使用示例 WPF 应用执行完全相同的操作。现在看看 MainWindow.g.cs(再次编辑以适应和删除无聊的部分):
public partial class MainWindow : System.Windows.Window,
System.Windows.Markup.IComponentConnector,
System.Windows.Markup.IStyleConnector {
private bool _contentLoaded;
public void InitializeComponent() {
//...
}
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
//...
}
void System.Windows.Markup.IStyleConnector.Connect(int connectionId, object target) {
switch (connectionId)
{
case 1:
#line 9 "..\..\MainWindow.xaml"
((System.Windows.Controls.TextBlock)(target)).MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(this.Item_Clicked);
//...
break;
}
}
大不同,现在您做 看到 MouseLeftButtonDown 事件回来了。显然,IStyleConnector
界面有助于订阅该事件。
所以去看看那个界面的MSDN article。相当简短,这是你不应该知道的内部管道,描述是:
Provides methods used internally by the WPF XAML parser to attach events and event setters in compiled XAML.
当然,与您要完成的目标完全匹配。该文章中最重要的是版本信息部分。在 .NET Framework 中受支持,但 Silverlight 未 列出。
这为您提供了 "why",必要的管道在 Silverlight 中根本不可用。否则不足为奇,Silverlight 最重要的属性是它 小 ,允许快速下载,当用户浏览到使用的网页时不会减慢用户的速度它。它只能通过删除东西来变小。
所以,显然你应该自己提供管道。你怎么做到这一点?受启发的 google 查询是 silverlight datatemplate event. The very first hit is a winner, a question,它试图完全 您正在做的事情。如果您需要更多帮助,可以使用更多相关匹配项。