Sean Edwards
Sean Edwards

Reputation: 2093

Wpf Recursive Binding

I'm trying to figure out how to build a recursive binding in xaml. I know about HierarchialDataTemplate, but that's not what I want, because my data source is not a collection of items. Specifically, I'm building an exception browser, and am trying to figure out the best way of expressing the exception's InnerException field (which is of course another exception, hence recursion.)

This exception browser is part of a log viewer I'm building. Here is the XAML for the ListView so far:

<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>

Any ideas? Is this even possible?

Upvotes: 2

Views: 1919

Answers (2)

Jesper Larsen-Ledet
Jesper Larsen-Ledet

Reputation: 6723

code to support getting the Exception type for the header:

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>

Upvotes: 0

Bryan Anderson
Bryan Anderson

Reputation: 16129

I would make a DataTemplate for an Exception and bind the InnerException to a ContentPresenter within it. The ContentPresenter will stop the chain when InnerExpception is null and you can format the exceptions however you want. Something like this:

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

Upvotes: 3

Related Questions