2009-11-12 46 views
2

我想弄清楚如何在xaml中建立一個遞歸綁定。我知道HierarchialDataTemplate,但這不是我想要的,因爲我的數據源不是項目的集合。具體來說,我正在構建一個異常瀏覽器,並試圖找出表達異常的InnerException字段的最佳方式(當然這是另一個例外,因此遞歸)。Wpf遞歸綁定

此異常瀏覽器是日誌查看器的一部分我正在建設。以下是目前用於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> 

任何想法?這甚至有可能嗎?

回答

3

我會爲Exception創建一個DataTemplate,並將InnerException綁定到其中的ContentPresenter。 ContentPresenter將在InnerExpception爲null時停止鏈,並且您可以根據需要設置異常的格式。是這樣的:

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

嗯。這非常接近,但它似乎只是將InnerException作爲一個字符串呈現。我希望可以像頂級異常一樣遞歸呈現(如Visual Studio的異常瀏覽器)。 –

+0

您可能需要將鍵分配給DataTemplate,然後將其明確分配,但您可能最終會得到類似的結果。 –

+0

這應該可以正常工作,但是您需要將它放在資源集合中的某個位置,您可以在該位置綁定外部異常,如Window.Resources。要啓動遞歸綁定,您應該在上例中設置Expander.Content =「{Binding Exception}」。我想在這一點上,你可能也想要移動的東西,所以你可能有擴展在你的例外模板,但你可以試試看,當你運行。 –

0

代碼來支持獲取異常類型爲標頭:

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>