Thanks to suggestion by @M Patel and Stefano, I've arrived at the following solution
var sorted = searches.Select(tile => new { TileViewModel = tile, Rank = rankResult(tile, text) })
.OrderByDescending(r => r.Rank)
.Select(r => r.TileViewModel);
SearchResultsTilesVM = new ObservableCollection<TileViewModel>(sorted);
The method that take the position of the keyword. I added extra point if a match is found in the title.
private int rankResult(TileViewModel vm, string keyword)
{
double rank = 0;
//Added 100 to give stronger weight when keyword found in title
int index = vm.Title.IndexOf(keyword, StringComparison.InvariantCultureIgnoreCase);
if (index >= 0 )
{
rank = (double)(vm.Title.Length - index) / (double)vm.Title.Length * 100 + 100;
}
int index2 = vm.Information.IndexOf(keyword, StringComparison.InvariantCultureIgnoreCase);
if (index2 >= 0)
{
rank += (double)(vm.Information.Length - index2) / (double)vm.Information.Length * 100;
}
return Convert.ToInt32(rank);
}