Niestandardowy układ / wirtualizacja WPF

To, co próbuję osiągnąć za pomocą WPF. Blok tekstowy jako przyciski tytułu i poniżej w awrappanel Problem polega na tym, że wymaga to przewijania itp. Osiągnąłem to za pomocą ItemsControl i wiązania dla każdej grupy. Mam ItemsControl, który ma stackpanel jako paneltemplate, a jego itemtemplate jest blokiem tekstowym i wrappanel.

Działa, ale jest powolny w tworzeniu instancji w wolnych maszynach intel gma + atom, gdy jest ich wiele. Wydaje się, że renderowanie nie jest problemem, ale tworzenie drzewa wizualnego. Więc moim jedynym założeniem jest stworzenie niestandardowego panelu z wirtualizacją?

Oto co zrobiłem.http://pastebin.com/u8C7ddP0
Powyżej niektóre rozwiązania są powolne.

Szukam rozwiązania, którego utworzenie na wolnych maszynach zajęłoby maksymalnie 100 ms. Dziękuję Ci

AKTUALIZACJA

 public class PreferenceCheckedConvertor : IMultiValueConverter
    {


    public object Convert(object[] values, Type targetType,
            object parameter, System.Globalization.CultureInfo culture)
    {

        var preference = values[0] as OrderItemPreference;
        var items = values[1] as ObservableCollection<OrderItemPreference>;

        var found = items.FirstOrDefault(item => item.Preference.Id == preference.Preference.Id);
        if (found == null)
        {
            return false;
        }
        return true;

    }
    public object[] ConvertBack(object value, Type[] targetTypes,
           object parameter, System.Globalization.CultureInfo culture)
    {
        try
        {
            return null;
        }
        catch (Exception e)
        {
            return null;
        }
    }


}

ff

public class PreferenceConvertor : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType,
                object parameter, System.Globalization.CultureInfo culture)
        {
            var preferences=values[0] as IEnumerable<Preference>;
            var items=values[1] as ObservableCollection<OrderItemPreference>;

            var newList = new List<OrderItemPreference>(preferences.Count());



            foreach (var preference in preferences)
            {
                var curItem = items.FirstOrDefault(item => item.Preference.Id == preference.Id);

                if (curItem == null)
                {
                    newList.Add(new OrderItemPreference()
                    {
                        Preference = preference
                    });
                }
                else
                {
                    newList.Add(curItem);
                }

            }

            return newList;







        }
        public object[] ConvertBack(object value, Type[] targetTypes,
               object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                return null;
            }
            catch (Exception e)
            {
                return null;
            }
        }}

questionAnswers(1)

yourAnswerToTheQuestion