Reputation: 3314
I have The following structure
QPage
class Object contains a List<List<QLine>>
QLine
object contains List<Qword>
every list of words constructs a line and every list of lines consists a group(paragraph) and every list of paragraphs consists a page.
I want to bind the page to structure like this in XAML
<ListView>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock>
</TextBlock>
</StackPanel>
</StackPanel>
</ListView>
where each item of the ListView is a paragraph(List<QLine>
) and each vertical stack panel holds an item of the List<QLine>
and each item of the horizontal stack panel holds an item of the List<Qword>
and the texblock is bound to Qword.text
property. I have no idea how to do such binding from the XAML code.
Upvotes: 3
Views: 1637
Reputation: 33394
Hopefully I did not miss some list but this should work. Basically it's a ListBox
that hosts List<List<QLine>>
(called it QPageList
). Then you have ItemsControl
that hosts each List<QLine>
in vertical panel and finally there is another ItemsControl
that hosts List<Qword>
from QLine
(called it QwordList
) where each QWord
is displayed as TextBlock
on horizontal StackPanel
<!-- ItemsSource: List<List<QLine>>, Item: List<QLine> -->
<ListBox ItemsSource="{Binding QPageList}">
<ListBox.ItemTemplate>
<DataTemplate>
<!-- ItemsSource: List<QLine>, Item: QLine -->
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- ItemsSource: QLine.List<QWord>, Item: QWord -->
<ItemsControl ItemsSource="{Binding QwordList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- Item: QWord -->
<TextBlock Text="{Binding text}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Upvotes: 4
Reputation: 5480
Forward to what Alex is saying, it'd be a good idea to Encapsulate
(If that's the correct word here) the object within classes, i.e.:
public class Page
{
public List<Paragraph> Paragraphs { get; set; }
}
public class Paragraph
{
public List<QWord> Sentences { get; set; }
}
public class Sentence
{
public List<QWord> Words { get; set; }
}
That'd help when you bind data in your XAML, i.e. if you look at the tutorial which Alex provided:
<TextBlock Text="Name: " />
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Text="{Binding Age}" FontWeight="Bold" />
<TextBlock Text=" (" />
<TextBlock Text="{Binding Mail}" TextDecorations="Underline" Foreground="Blue" Cursor="Hand" />
<TextBlock Text=")" />
Hope that helps you.
Upvotes: 0
Reputation: 9725
Hopefuly this will prove helpful. Taken from here
Authors (list)
- - Name
- - Books (list)
| - - Title
| - - Contents
Sample code :
<Window.Resources>
<DataTemplate x:Key="ItemTemplate1">
<StackPanel>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="ItemTemplate2">
<StackPanel>
<TextBlock Text="{Binding Title}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource AuthorDataSource}}">
<ListBox x:Name="AuthorList" ItemTemplate="{DynamicResource ItemTemplate1}" ItemsSource="{Binding Authors }" >
<ListBox x:Name="BookList" DataContext="{Binding SelectedItem, ElementName=AuthorList}" ItemsSource="{Binding Books }" ItemTemplate="{DynamicResource ItemTemplate2}" />
<TextBlock x:Name="BookContent" DataContext="{Binding SelectedItem, ElementName=BookList}" Text="{Binding Contents }" />
</Grid>
Upvotes: 0
Reputation: 1109
What you are looking for is ListView.ItemTemplate
. Basically, you need to provide your list with a way to understand the nested data structure of your rows.
Here is a good tutorial to get you started on ItemTemplates.
Once your list has an item template then you just bind the ListView directly to your data source and that's it.
Upvotes: 1