WPF DataTemplate绑定与嵌套在ListBox中的ItemsControl一起使用时不起作用

时间:2011-06-21 23:13:44

标签: wpf xaml data-binding datatemplate

我有一个UserControl,它包含一个ListBox,它绑定到一个名为Data的CollectionViewSource,该集合中的每个项目都使用ItemTemplate显示在ListBox中。 ItemTemplate是一个ItemsControl,绑定到另一个名为Rows的CollectionViewSource。行存储一个或多个MyListBoxRow对象。对于Data CollectionViewSource中的每个对象,我得到一个ListBoxItem,它由Rows CollectionViewSource中的ContentPresenters组成。

我这样做的原因是我可以在运行时操作Rows集合并添加/删除“行”信息。

我遇到的问题是“NumberDescriptionDataTemplate”,“NotesDataTemplate”和“AuditDataTemplate”DataTemplates中的数据绑定。例如,NotesDataTemplate中的{Binding Notes}不起作用,因为绑定的当前项是来自Rows而不是Data。如果我将NotesDataTemplate更改为{Binding Description},我会按预期从MyListBoxRow对象获取Description。

如何修改DataTemplates中的Binding语句,以便将信息绑定到Data集合中的项目而不是Rows集合中的项目?

... MyListBox.xaml

<UserControl x:Name="MyListBox"...>
<UserControl.Resources>
    <CollectionViewSource x:Key="Data" Source="{Binding ItemsSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
    <CollectionViewSource x:Key="Rows" Source="{Binding ListRows, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" Filter="Rows_Filter" />
</UserControl.Resources>

<ListBox ItemsSource="{Binding Source={StaticResource Data}}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding Source={StaticResource Rows}}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <ContentPresenter ContentTemplate="{Binding RowTemplate}"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
</UserControl>

“MyListBox”正在使用中......

<Window...>
<Window.Resources>
    <DataTemplate x:Key="NumberDescriptionDataTemplate">
        <TextBlock Text="{Binding Number_Description}"  FontSize="20" />
    </DataTemplate>
    <DataTemplate x:Key="NotesDataTemplate">
        <TextBlock Text="{Binding Description}"  />
    </DataTemplate>
    <DataTemplate x:Key="AuditDataTemplate">
        <TextBlock FontSize="8pt" FontStyle="Italic" TextTrimming="CharacterEllipsis">
            <TextBlock.Text>
                <MultiBinding StringFormat="{}Added On {0:ddd MMM dd, yyyy hh:mm:ss}; Last Modified On {1:ddd MMM dd, yyyy hh:mm:ss}; Removed On {2:ddd MMM dd, yyyy hh:mm:ss}">
                    <Binding Path="AddedOn" FallbackValue="[Added On]" TargetNullValue="n/a" />
                    <Binding Path="ModifiedOn" FallbackValue="[Modified On]" TargetNullValue="n/a" />
                    <Binding Path="RemovedOn" FallbackValue="[Removed On]" TargetNullValue="n/a" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </DataTemplate>
</Window.Resources>

<local:MyListBox ItemsSource="{Binding Samples}">
    <local:MyListBox.ListRows>
        <local:MyListBoxRow Description="Number, Description"  
                            IsDisplayed="True"  
                            IsRequired="True" 
                            RowTemplate="{StaticResource NumberDescriptionDataTemplate}" />
        <local:MyListBoxRow Description="Notes" 
                            IsDisplayed="True" 
                            IsRequired="False" 
                            RowTemplate="{StaticResource NotesDataTemplate}" />
        <local:MyListBoxRow Description="Added, Modified, Removed" 
                            IsDisplayed="True" 
                            IsRequired="False" 
                            RowTemplate="{StaticResource AuditDataTemplate}" />
    </local:MyListBox.ListRows>
</local:MyListBox>
</Window>

1 个答案:

答案 0 :(得分:5)

如果那不是您需要的,那么您可以使用除DataContext之外的其他来源。使用ItemsControls时,您经常可能想要访问所述控件的DataContext而不是模板化的项目,因为您可以使用RelativeSource-Binding,例如。

{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext.Data}

这是一个例子,不太确定我得到了你的整个结构,你可能需要适应它。