Лично я бы (если предположить, что данные находятся в какой-то базе данных) разместил эти строки в некотором виде ItemsControl. ItemsControl будет привязан к коллекции Items.
Если бы у меня была небольшая свобода действий, я бы сделал это простым старым списком и настроил стиль элементов). Часть гистограммы в конце должна быть достаточно простой, если у нее есть прямоугольник, ширина которого привязана к свойству оценки, или что-либо еще, которое применяется в процентах от ширины контейнера, в котором оно находится.
Таким образом, у меня будет Subject Class (который создается из источника данных) с несколькими свойствами:
Имя (например, «Таблицы времени»), представленное TextBlock
Оценка (например, 52%) Представляется прямоугольником, связанным со свойством, которое умножает это значение на ширину сетки, в которой находится прямоугольник
Действие (например, «Повторить»), представленное другим текстовым блоком.
Я скоро опубликую пример.
Пример
ОК, поэтому окно имеет очень простую компоновку, сетку со списком. Окно списка связано с источником данных времени разработки, который я настроил в Expression Blend.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TreeViewMFagic"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
x:Class="MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot" MouseRightButtonDown="ShowContext" DataContext="{Binding Source={StaticResource dsSubjects}}">
<ListBox ItemTemplate="{DynamicResource ItemTemplate}" ItemsSource="{Binding Collection}" HorizontalContentAlignment="Stretch"/>
</Grid>
</Window>
ItemTemplate, который я помещаю в библиотеку ресурсов App.Xaml, так как мне нравится, чтобы мои файлы Window и UserControl xaml были красивыми и чистыми, и как можно больше использовал словари ресурсов, чтобы не мешать вещам. Во всяком случае, ниже находится ItemTemplate.
<DataTemplate x:Key="ItemTemplate">
<Grid Height="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.029*"/>
<ColumnDefinition Width="0.67*"/>
<ColumnDefinition Width="0.168*"/>
<ColumnDefinition Width="0.133*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding SubjectName}" VerticalAlignment="Bottom" d:LayoutOverrides="Width" Grid.ColumnSpan="1" Margin="0" Grid.Column="1"/>
<TextBlock Text="{Binding Action}" VerticalAlignment="Top" d:LayoutOverrides="Width, GridBox" Grid.ColumnSpan="1" Grid.Column="3" Margin="0"/>
<Border Grid.ColumnSpan="1" Grid.Column="2" Margin="0" d:LayoutOverrides="Height" Background="#A3000000" CornerRadius="5" Width="{Binding PercentCorrect}" HorizontalAlignment="Left" >
<TextBlock Text="{Binding PercentCorrect}" HorizontalAlignment="Center"/>
</Border>
<TextBlock TextWrapping="Wrap" Text="{Binding Number}" d:LayoutOverrides="Width, Height"/>
</Grid>
</DataTemplate>
И готовый продукт выглядит так:
Теперь я немного обманул здесь. Я привязал ширину элемента границы для оценки прямо к проценту. Если бы у меня было больше времени возиться с этим, я, вероятно, сделал бы ViewModel и имел значения как для заштрихованной, так и не заштрихованной частей, которые составляли до 100%. Затем ограничьте ширину столбца сетки, в которую я бы поместил границу для этих значений, чтобы иметь истинный процент. Независимо от этого, есть отправная точка.