【问题标题】:WPF: TreeViewItem Expanded/Collapsed Event Catches ExceptionsWPF:TreeViewItem 展开/折叠事件捕获异常
【发布时间】:2018-04-08 03:00:33
【问题描述】:

我正在使用 C# 开发 WPF 应用程序,并且遇到了一个有趣的问题。为什么忽略 TreeViewItem 中的展开/折叠事件引发的异常?其他事件,包括像 MouseDoubleClick 这样的 TreeViewItem 中的事件,表现出异常的正常行为。 Visual Studio 中的诊断工具显示异常被抛出,然后在 PresentationFramework 代码中被捕获。例如,

XAML

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TreeView>
            <TreeViewItem Header="Parent" Expanded="TreeViewItem_Expanded" MouseDoubleClick="TreeViewItem_MouseDoubleClick">
                <TreeViewItem Header="Child" />
            </TreeViewItem>
        </TreeView>
    </Grid>
</Window>

XAML.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
    {
        throw new Exception("Ignored"); //Same issue with Collapsed event
    }

    private void TreeViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        throw new Exception("Normal exception behavior");
    }
}

我正在实现一个延迟加载的 TreeView,我花了一天的大部分时间来调试我的应用程序,却发现它静悄悄地失败了,而最初的问题是一个简单的修复。我使用 Expanded 和 Collapsed 事件的方法完全错误吗?如果没有,是否有任何优雅的方法可以不让这些异常静默失败?

【问题讨论】:

    标签: c# wpf xaml data-binding treeviewitem


    【解决方案1】:

    此行为并非特定于 Expanded 事件或任何其他事件。

    原因是您的异常被 WPF 绑定引擎“吞噬”了。 TreeViewItem 的默认 ControlTemplate 包含一个 ToggleButton,它使用双向模式将其 IsChecked 属性绑定到 TreeViewItem.IsExpanded 属性:

    <ToggleButton IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"/>
    

    所以整个过程是这样的:

    1. 您单击项目的展开图标(实际上,这是ToggleButton)。
    2. ToggleButton 将其IsChecked 属性设置为true
    3. WPF 绑定引擎将新值 (true) 传输到 TreeViewItemIsExpanded 属性。
    4. 树项展开并引发Expanded 事件。
    5. 您在事件处理程序中抛出异常。
    6. 由于我们仍在处理绑定传输(第 3 步),绑定引擎会捕获异常并将其记录到配置的 TraceListener
    7. 工作流继续,您在调用者的堆栈上看不到异常。

    WPF 绑定引擎本机捕获异常,您无法更改它。 但是你可以实现你自己的TraceListener,它可以抛出提供的异常或者做一些其他的错误处理。

    看看this question 及其答案。

    【讨论】:

      猜你喜欢
      • 2012-02-29
      • 2012-01-14
      • 2014-04-14
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-12
      相关资源
      最近更新 更多