我正在尝试创建Windows Phone 8.1应用程序。每当我尝试获取DataTemplate的子代(这是必要的,因为它们嵌入在ListView中)时,我会得到一个详细描述的异常
灾难性故障(HRESULT异常:0x8000FFFF(E_UNEXPECTED))
我在这里做了一个非常简单的复制品:
在Visual Studio中,创建一个新的Windows Phone Blank App模板。在MainPage.xaml的OnNavigatedTo事件处理程序中,添加一行代码:
var count = VisualTreeHelper.GetChildrenCount(new DataTemplate());
当你调试这个应用程序时,它直接表示"在用户代码中发生了未处理的System.Exception。"
我检查过MSDN以确保此方法不会抛出任何异常。
答案 0 :(得分:2)
它失败了,因为DataTemplate
不是视觉对象而且没有视觉孩子。 (显然VisualTreeHelper.GetChildrenCount
实际上没有检查你是否正在通过视觉传递,这就是为什么你会看到灾难性的失败而不是正常的异常。)
通常,您不需要查看ListView的可视化树。通常,您可以将ItemsSource设置为包含所需内容属性的自定义类的集合。
如果你仍然需要ListViewItem中的实际视觉效果 - 这是一个角落案例的最后手段 - 那么你创建一个自定义附加属性(-ies)并将它附加到DataTemplate中的相关视觉效果。当您附加的属性更改事件触发时,事件发送方将是相关的可视化对象,该发送方的DataContext将是该列表项的数据值。
例如,如果您在ListView
中有一个按钮并希望按钮单击以触发操作,那么您将执行以下操作:
<ListView.ItemTemplate>
<DataTemplate>
<Button MyClickHelper.ClickHandler="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
然后,在您的班级MyClickHelper
中:
private static void OnClickHandlerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var button = (Button)d;
var data = (MyDataType)e.NewValue;
button.Click += (btn, args) =>
{
// do action here based on data above
}
}
这称为附加行为 - 附加属性,用于修改按钮的行为。这是一个有用的模式,可以在代码的不同部分之间保持良好的界限,并允许每个按钮具有规定的行为,而不需要一些必须直接管理所有不同按钮的主类。