任何人都可以告诉我试图制作一个“嵌套”的东西。 WPF ItemsControl ...如果它甚至可以按照我想要的方式工作。 我有这个数据模型:
public class PlateItem
{
public Guid ID { get; set; }
public string Type { get; set; }
public string Caption { get; set; }
public int GridRow { get; set; }
public int GridColumn { get; set; }
// 0 or 2 Children
public ObservableCollection<PlateItem> Children { get; set; }
}
private void Initialize()
{
ObservableCollection<PlateItem> collection = new ObservableCollection<PlateItem>();
// Type = "Child" - Caption should be displayed
// Type = "Container" - Caption should not be displayed. Its Children of type "Visual" Captions should be displayed
PlateItem item_Main = new PlateItem() { Type = "Container", Caption = "ZERO", GridRow = 0, GridColumn = 0, ID = Guid.NewGuid(), Children = new ObservableCollection<PlateItem>() };
PlateItem item_Main_A = new PlateItem() { Type = "Child", Caption = "ONE", GridRow = 0, GridColumn = 0, ID = Guid.NewGuid(), Children = new ObservableCollection<PlateItem>() };
PlateItem item_Main_B = new PlateItem() { Type = "Container", Caption = "TWO", GridRow = 1, GridColumn = 0, ID = Guid.NewGuid(), Children = new ObservableCollection<PlateItem>() };
PlateItem item_Main_B_1 = new PlateItem() { Type = "Child", Caption = "THREE", GridRow = 0, GridColumn = 0, ID = Guid.NewGuid(), Children = new ObservableCollection<PlateItem>() };
PlateItem item_Main_B_2 = new PlateItem() { Type = "Child", Caption = "FOUR", GridRow = 1, GridColumn = 0, ID = Guid.NewGuid(), Children = new ObservableCollection<PlateItem>() };
item_Main_B.Children.Add(item_Main_B_1);
item_Main_B.Children.Add(item_Main_B_2);
item_Main.Children.Add(item_Main_A);
item_Main.Children.Add(item_Main_B);
collection.Add(item_Main);
this.PlateItemsSource = collection;
}
我需要一个嵌套控件:
现在我有了这个XAML,它不起作用:
<UserControl.Resources>
<!-- ************************************************** -->
<h:TemplateselectorPlateItem x:Key="TemplateselectorPlateItem"/>
<!-- should display PlateItems that don't have Children -->
<DataTemplate x:Key="DatatemplatePlateItemSingle">
<TextBox Background="Green" Margin="20"
Text="{Binding Path=Caption, Mode=TwoWay}" />
</DataTemplate>
<!-- should display PlateItems that has Children -->
<DataTemplate x:Key="DatatemplatePlateItemDouble">
<ItemsControl ItemsSource="{Binding Path=Children}"
ItemTemplate="{StaticResource DatatemplatePlateItemSingle}">
<ItemsControl.ItemContainerStyle>
<Style>
<Style.Setters>
<Setter Property="Grid.Row" Value="{Binding Path=GridRow}"/>
<Setter Property="Grid.Column" Value="{Binding Path=GridColumn}"/>
</Style.Setters>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</UserControl.Resources>
<ItemsControl ItemsSource="{Binding Path=PlateItemsSource}"
ItemTemplateSelector="{StaticResource TemplateselectorPlateItem}">
</ItemsControl>
TemplateSelector的代码:
public class TemplateselectorPlateItem : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null && item != null && item is PlateItem)
{
PlateItem plateItem = item as PlateItem;
if(plateItem.Children.Count == 0)
{
return element.FindResource("DatatemplatePlateItemSingle") as DataTemplate;
}
else
{
return element.FindResource("DatatemplatePlateItemDouble") as DataTemplate;
}
}
return null;
}
}
我想要实现的内容的非常粗略的直观表示http://www.trinitytilesupply.com/pattern2.jpg为什么我想使用这样的模型 - 我需要功能来分割任何&#34; Visual&#34;垂直或水平,代码意味着 - 改变一个来源PlateItem:&#34; Child&#34; -type to&#34; Container&#34; -type with 2 new children
答案 0 :(得分:1)
您需要调整DatatemplatePlateItemDouble,删除其ItemTemplate,而不是使用相同的ItemTemplateSelector。因此,它会递归地将DatatemplatePlateItemDouble应用于所有带子项的后代。
<DataTemplate x:Key="DatatemplatePlateItemDouble">
<ItemsControl ItemsSource="{Binding Path=Children}"
ItemTemplateSelector="{StaticResource TemplateselectorPlateItem}" >
...
您还需要更改/删除此行,这将导致无限递归。
item_Main.Children.Add(item_Main);