Wpf递归绑定

时间:2009-11-12 10:07:43

标签: c# wpf xaml recursion

我正在试图弄清楚如何在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>

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

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

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

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>