让DataTemplate的孩子们陷入“灾难性的失败”(WP 8.1)

时间:2015-02-14 17:14:14

标签: c# xaml windows-phone-8 windows-phone datatemplate

我正在尝试创建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以确保此方法不会抛出任何异常。

1 个答案:

答案 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
    }
}

这称为附加行为 - 附加属性,用于修改按钮的行为。这是一个有用的模式,可以在代码的不同部分之间保持良好的界限,并允许每个按钮具有规定的行为,而不需要一些必须直接管理所有不同按钮的主类。