【问题标题】:Wpf Recursive BindingWpf 递归绑定
【发布时间】:2010-12-15 19:50:09
【问题描述】:

我试图弄清楚如何在 xaml 中构建递归绑定。我知道 HierarchialDataTemplate,但这不是我想要的,因为我的数据源不是项目的集合。具体来说,我正在构建一个异常浏览器,并试图找出表达异常的 InnerException 字段的最佳方式(这当然是另一个异常,因此是递归。)

这个异常浏览器是我正在构建的日志查看器的一部分。到目前为止,这是 ListView 的 XAML:

<ListView x:Name="LogViewerOutput">
    <ListView.ItemTemplate>
        <DataTemplate DataType="Ushanka.Log.LogMessageEventArgs">
            <Expander Style="{StaticResource ExceptionTreeStyle}" Width="Auto">
                <Expander.Header>
                    <StackPanel Orientation="Horizontal">
                        <Image Stretch="Fill" Width="16" Height="16" Margin="5" 
                               Source="{Binding Path=Level, Converter={StaticResource LogLevelIconConverter}}" />
                        <TextBlock Text="{Binding Message}" />
                    </StackPanel>
                </Expander.Header>
                <Expander.Content>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Text="{Binding Exception.Message}" />
                        <TextBlock Text="{Binding Exception.Source" />
                        <!-- Here I would like to somehow be able to recursively browse through the tree of InnerException -->
                    </StackPanel>
                </Expander.Content>
            </Expander>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

有什么想法吗?这甚至可能吗?

【问题讨论】:

    标签: c# wpf xaml recursion


    【解决方案1】:

    我会为异常创建一个 DataTemplate 并将 InnerException 绑定到其中的 ContentPresenter。当 InnerExpception 为空时,ContentPresenter 将停止链,您可以根据需要格式化异常。像这样的:

    <DataTemplate DataType="{x:Type Exception}">
        <StackPanel Orientation="Vertical">
            <TextBlock Text="{Binding Message}" />
            <TextBlock Text="{Binding Source"   />
            <ContentPresenter Content="{Binding InnerException}"    />
        </StackPanel>
    </DataTemplate>
    

    【讨论】:

    • 嗯。这非常接近,但似乎只是将 InnerException 呈现为字符串。我希望它可以以与顶级异常相同的方式递归呈现(如 Visual Studio 的异常浏览器)。
    • 您可能需要为 DataTemplate 分配键并明确分配它,但您最终可能会得到这样的结果。
    • 这应该可以按原样工作,但您需要将其放置在您绑定外部异常的控件上方的某个资源集合中,例如 Window.Resources。要启动递归绑定,您只需在上面的示例中设置 Expander.Content="{Binding Exception}" 。我猜那时你可能还想移动一些东西,所以你可能在你的异常模板中有扩展器,但是当你运行它时你可以尝试一下。
    【解决方案2】:

    支持获取标头的异常类型的代码:

    class TypeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value.GetType().ToString();
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    xaml:

    <Window.Resources>
    
        <local:TypeConverter x:Key="TypeConverter"/>
    
        <DataTemplate DataType="{x:Type sys:Exception}">
            <Expander Header="{Binding Converter={StaticResource TypeConverter}}">
                <Expander.Content>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Text="{Binding Message}" />
                        <TextBlock Text="{Binding Source}"   />
                        <ContentPresenter Content="{Binding InnerException}"    />
                    </StackPanel>
                </Expander.Content>               
            </Expander>
        </DataTemplate>   
    
    </Window.Resources>
    

    【讨论】:

      猜你喜欢
      • 2014-10-09
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      • 2012-03-30
      • 1970-01-01
      • 1970-01-01
      • 2011-02-09
      • 1970-01-01
      相关资源
      最近更新 更多