Reputation: 333
I am building a webscaper to scrape torrents, backend is already done and now I am kind of stuck on the UI(using WPF).
I want to display the torrents on a ListBox
but corresponding to the query (I call it term as in search term).
The data passed to the ListBox
is:
List<SearchTermData>
This is the structure:
public class SearchTermData {
public string SearchTerm { get; set; }
public List<Torrent> Torrents { get; set; } = new List<Torrent>();
}
Torrent is this:
public class Torrent {
public string Name { get; set; }
public string Size { get; set; }
}
I generally want the ListBox
to display a Grid
. Column 1 will be the "SearchTerm" and column 2 will be a StackPanel
of "Torrents" (List<Torrent>
).
It displays the "SearchTermData" correctly, with the SearchTerm
name and the general structure, but it fails to display the StackPanel
of the Torrents
.
This is my XAML style:
<Style x:Key="TorrentListbox" TargetType="ListBox">
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="{StaticResource Black}"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="SelectionMode" Value="Multiple" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="ItemContainerStyle" Value="{DynamicResource TermItem}" />
</Style>
<Style x:Key="TermItem" TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="{StaticResource DSGray}"/>
<Setter Property="Foreground" Value="{StaticResource Black}" />
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Margin" Value="0,0,0,4"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="0" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<Grid Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="{Binding Path=SearchTerm}" BorderThickness="0,0,2,0" BorderBrush="{StaticResource Black}" Style="{StaticResource KeyLabel}" Foreground="{StaticResource DSGreen}" FontWeight="Bold" VerticalContentAlignment="Top" Grid.Row="0" Grid.Column="0"/>
<StackPanel Grid.Row="0" Grid.Column="1">
<ItemsControl ItemsSource="{Binding Path=Torrents}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="{StaticResource DSGreen}">
<ItemsControl ItemsSource="{Binding Torrent}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="{Binding Path=Name}" Style="{StaticResource PropertyLabel}" Grid.Row="0" Grid.Column="0"/>
<Label Content="Size:" Style="{StaticResource KeyLabel}" Grid.Row="0" Grid.Column="1"/>
<Label Content="{Binding Path=Size}" Style="{StaticResource PropertyLabel}" Grid.Row="0" Grid.Column="2"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If anyone can help me figure out the issue I would appreciate it a lot!
Upvotes: 0
Views: 397
Reputation: 22119
In your items template for Torrent
, there is a nested ItemsControl
that is not needed and that is binding to a property Torrent
on an item of type Torrent
, which does not exist.
<ItemsControl ItemsSource="{Binding Torrent}">
The control template below should work. I removed the redundant ItemsControl
and the StackPanel
as well, because it only contains a single control, which is why you do not need it.
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="0" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<Grid Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="{Binding Path=SearchTerm}" BorderThickness="0,0,2,0" BorderBrush="{StaticResource Black}" Style="{StaticResource KeyLabel}" Foreground="{StaticResource DSGreen}" FontWeight="Bold" VerticalContentAlignment="Top" Grid.Row="0" Grid.Column="0"/>
<ItemsControl Grid.Row="0" Grid.Column="1" ItemsSource="{Binding Path=Torrents}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="{StaticResource DSGreen}">
<Grid HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="{Binding Path=Name}" Style="{StaticResource PropertyLabel}" Grid.Row="0" Grid.Column="0"/>
<Label Content="Size:" Style="{StaticResource KeyLabel}" Grid.Row="0" Grid.Column="1"/>
<Label Content="{Binding Path=Size}" Style="{StaticResource PropertyLabel}" Grid.Row="0" Grid.Column="2"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
</ControlTemplate>
Since you want to display two columns, you could alternatively use a ListView
in combination with a GridView
. This way, you would actually have real columns.
<ListView ItemsSource="{Binding SearchTerms}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="{StaticResource DSGray}"/>
<Setter Property="Foreground" Value="{StaticResource Black}" />
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Margin" Value="0,0,0,4"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="0" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<GridViewRowPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Search Term">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Path=SearchTerm}" BorderThickness="0,0,2,0" BorderBrush="Black" Foreground="Green" FontWeight="Bold"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Torrents">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Torrents}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Green">
<Grid HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="{Binding Path=Name}" Grid.Row="0" Grid.Column="0"/>
<Label Content="Size:" Grid.Row="0" Grid.Column="1"/>
<Label Content="{Binding Path=Size}" Grid.Row="0" Grid.Column="2"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Upvotes: 1