Это делает то, что вы хотите:
var result = Enumerable.Range(0, items.Max(x => x.Index) + 1)
.Select(i => items.Where(x => x.Index == i)
.Select(x => x.Text)
.SingleOrDefault())
.ToList();
Результат:
result[0] = null
result[1] = Data #1
result[2] = null
result[3] = null
result[4] = Data #3
result[5] = null
result[6] = null
result[7] = null
result[8] = Data #8
Вы можете повысить производительность, сохранив исходные данные в словаре:
Dictionary<int, string> d = items.ToDictionary(x => x.Index, x => x.Text);
List<string> result = new List<string>();
for (int i = 0; i < d.Keys.Max() + 1; ++i)
{
string s;
d.TryGetValue(i, out s);
result.Add(s);
}