【问题标题】:Getting children of DataTemplate throws "catastrophic failure" (WP 8.1)获取 DataTemplate 的孩子会引发“灾难性失败”(WP 8.1)
【发布时间】:2015-02-14 17:14:14
【问题描述】:

我正在尝试创建一个 Windows Phone 8.1 应用程序。每当我尝试获取 DataTemplate 的子项(这是必要的,因为它们嵌入在 ListView 中)时,我都会收到一个详细信息的异常

灾难性故障(HRESULT 异常:0x8000FFFF (E_UNEXPECTED))

我在这里做了一个非常简单的repro:

在 Visual Studio 中,创建一个新的 Windows Phone 空白应用模板。在 MainPage.xaml 的 OnNavigatedTo 事件处理程序中,添加一行代码

var count = VisualTreeHelper.GetChildrenCount(new DataTemplate());

当您调试此应用程序时,它会直接说“用户代码中发生了未处理的 System.Exception。”

我已检查 MSDN 以确保此方法不应引发任何异常。

【问题讨论】:

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


    【解决方案1】:

    它失败了,因为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
        }
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      • 2019-02-19
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多