所以,我的想法是,我有一个ListView
使用Template1
作为DataTemplate
,然后包含另一个ListView
Template2
,使用Cars
第一个DataContext
的绑定/ datacontext。因此Template2
的{{1}}应该是Template1
DataContext.Cars
,应该用作DataTemplate2
的绑定。
有可能吗?怎么???
型号:
class Reseller
{
public Dictionary<int, Car> Cars;
...
}
class Car
{
public string Model { get; set; }
public string Year { get; set; }
...
}
我有两个这样的DataTemplates:
<!--Template1 contains a Dictionary<string, Reseller>-->
<!-- Reseller has another dictionary of Cars like Dictionary<int, Car>-->
<DataTemplate x:Key="Template1">
<StackPanel Orientation="Horizontal">
<GroupBox Header="{Binding Key}">
<ListView x:Name="Internal_Template2
ItemTemplate="{StaticResource Template2}"/>
</GroupBox>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="Template2">
<Grid>
<TextBlock Text="{Binding Template1.Value.Cars.Model}"/>
<TextBlock Text="{Binding Template1.Value.Cars.Year}"/>
</Grid>
</DataTemplate>
这是我想要创建的内容的快速绘图。 BranchX是一个ListView
,它包含Cars
,这是另一个`ListView,来自BranchX的Cars属性:
答案 0 :(得分:2)
是的,这是可能的。我将向您展示根据我的项目改编的示例,其中我在另一个ItemsControl中使用ItemsControl。这可以适用于除ItemsControl之外的其他容器,但ItemsControl提供了最大的灵活性。 如果我理解正确,您希望显示经销商列表,并且对于每个经销商,您希望显示汽车列表。
对于每个 ResellerInfo 项,外部ItemsControl将显示一个带有TextBlock的StackPanel和另一个显示Cars的ItemsControl。
然后,内部ItemsControl会显示每个车辆的模型和年份的StackPanel。请注意,内部的DataContext会自动设置为 CarInfo 的实例。
作为奖励,我们正在使用VirtualizingStackPanel,它不会渲染屏幕外的项目 - 如果您的数据库很大,这可以派上用场。
作为主控件的 DataContext 的viewmodel需要定义:
public ObservableCollection<ResellerInfo> Resellers
ResellerInfo 是一个具有以下属性的类:
public String ResellerName
public ObservableCollection<CarInfo> Cars
CarInfo 是一个具有以下属性的类:
public String Model
public String Year
需要调用所有属性的setter
NotifyPropertyChanged();
中定义
XAML:
<ItemsControl ItemsSource="{Binding Resellers}" >
<!-- Template specifies how this ItemsControl looks like -->
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer Margin="5">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<!-- ItemsPanel holds items. Use it to change the way items are laid out -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ItemTemplate specifies how each item is displayed -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- BEGINNING OF SINGLE ITEM CODE -->
<StackPanel>
<TextBlock Text="{Binding ResellerName}" />
<ItemsControl ItemsSource="{Binding Cars}">
<!-- Template specifies how this ItemsControl looks like -->
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer Margin="5">
<ItemsPresenter />
</ScrollViewer >
</ControlTemplate>
</ItemsControl.Template>
<!-- ItemsPanel holds items. Use it to change the way items are laid out -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ItemTemplate specifies how each item is displayed. -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Model}" />
<TextBlock Text="{Binding Year}" />
</StackPanel>
<DataTemplate>
</ItemsControl.ItemTemplate> -->
</ItemsControl>
</StackPanel>
<!-- END OF SINGLE ITEM CODE -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我在StackOverflow上编写了代码,如果您发现错误,请随时更正!
答案 1 :(得分:1)
在 ListView 中分配 ItemsSource (我假设您在代码隐藏中执行此操作)时,每个项目的 DataContext 设置为他们的模型表示。例如:
ListView (DataContext: Resellers)
|-- ListViewItem (DataContext: Resellers[0])
|-- ListViewItem (DataContext: Resellers[1])
`-- etc...
因此您无需访问父 DataTemplate 的 DataContext 。实际上, Template2 的 DataContext 会自动设置为Resellers[].Value.Cars[]
。这允许您将 TextBlock 绑定到Value
:
<DataTemplate x:Key="Template2">
<Grid>
<TextBlock Text="{Binding Value.Model}"/>
<TextBlock Text="{Binding Value.Year}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="Template1">
<GroupBox Header="{Binding Key}">
<ListView x:Name="Internal_Template2
ItemsSource="{Binding Value.Cars}"
ItemTemplate="{StaticResource Template2}"/>
</GroupBox>
</DataTemplate>
您无法让 ListView 在 ItemTemplate 中显示其项目水平,您需要将 ItemsPanel 属性添加到您的转销商的ListView :
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>