Optymalizacja dodawania wierszy w DataGridView

1

Witam, mam pewien jak dla mnie nie do końca zrozumiały problem. Aplikacja posiada formatkę zawierającą prosty DataGridView "DGV " reprezentujący dane z różnych źródeł. W metodzie Load() formatki inicjalizowany jest DGV wygląda to mniej więcej tak. Dane przechowywane są w zbiorze:

List<Dictionary<string, object>> 

Wczytywanie wiersz wygląda tak

this.Rows.Add(lData.Count);
foreach (Dictionary<string, object> row in lData)
{
    AddRow(row);
}

Gdzie AddRow to metoda uzupełniające w zależności od kontekstu wiersze DGV. Czas wykonania dla 1000 wierszy metodzie Load() to około ~-0.12 sek. Natomiast wywołanie odświeżenia listy wierszy zajmuje już poza metodą Load() to ponad 2 sek. Wydaje mi się, że ta duża różnica wynika z kontekstu użycia, w metodzie Load() formatka nie rysuje danych na bieżąca, natomiast w drugim przypadku zmiany są dodawane w czasie wykonywania?

W jaki sposób mogę zoptymalizować kod, tak aby otrzymać dobry początkowy wynik?

0

Pierwsze - jaka technologia - DGV występuję chyba w WinForms, WPF, Silverlight, WebForms.
Drugie - więcej kodu, co rozumiesz przez odświeżenie?
Trzecie - List<Dictionary<string, object>> - to nie wygląda za dobrze, co ładujesz do tego DGV?

0
  1. WinForms
  2. Odświeżenie czyli wykonanie
DGV.Rows.Clear();

, a następnie foreach(...){ DGV.Rows.Add(lData[...].toArray()) }

3. Wiersz po wierszu w zależności od danych...
0

Widzisz, to co robisz to nie odświeżenie, tylko skasowanie i wypisanie danych na nowo, wiersz po wierszu.
Przypuszczam, że różnica w czasie wynika z problemu odrysowywania - kontrolka, z każdym dodaniem wiersza, musi zostać wyrenderowana na nowo. W metodzie Load działa to dość szybko, ponieważ kontrolka nie musi być przerysowywana, ponieważ jej jeszcze nie ma na formularzu (skrót myślowy).
DGV w WinForms posiada mechanizmy Bindingu i Datasource - powinieneś z nich korzystać - uprości to zdecydowanie kod i go zautomatyzuje. Tutaj masz tutorial jak tego używać: http://www.dotnetperls.com/datagridview

0

A w jaki sposób mogę wyłączyć renderowanie? Którą/e metody renderujące powinienem przegiąć i w czasie wpisywania wyłączyć?

2

Nie powinieneś wyłączać renderowania, tylko zmienić podejście do problemu. Taki sposób jak działasz na DGV jest kiepski, wywodzi się prawdopodobnie z czasów pierwszych wrapperów na WinAPI i pokutuje do dziś, chyba tylko w celu zachowania kompatybilności starych tutoriali w internecie ;)
Obecnie stosuje się w tym celu wiązanie danych (data binding). Prosty przykład:

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    public partial class Form1 : Form
    {
        private BindingList<Person> persons;
        private List<Person> persons10000;
        private BindingList<Person> personsBinding10000;

        Random rand = new Random();

        public Form1()
        {
            InitializeComponent();

            persons = new BindingList<Person>()
                {
                    new Person() {Name = "Mietek", Age = 24},
                    new Person() {Name = "Ździsław", Age = 32}
                };

            dataGridView1.DataSource = persons;

            persons10000 = new List<Person>(10000);
            for (int i = 0; i < 10000; i++)
            {
                persons10000.Add(new Person() { Name = i.ToString(), Age = rand.Next(0,99)});
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            personsBinding10000 = new BindingList<Person>(persons10000);
            dataGridView1.DataSource = personsBinding10000;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            persons.Add(new Person() { Name = "Halina", Age = 28 });
        }
    }

Na formie wrzucone tylko DGV i 2 buttony.
Zgadnij ile zajmuje mi wyświetlenie 100000 osób na liście? 0, jeśli rzutujemy wynik na int ;) Zwróć też uwagę w przypadku drugiego przycisku, że po dodaniu osoby do listy, lista DGV automagicznie się "odświeża".

0
ikolppo napisał(a):

Pierwsze - jaka technologia - DGV występuję chyba w WinForms, WPF, Silverlight, WebForms.

W WPF jest DataGrid.
W WebFormsach jest GridView.
A DataGridView jest tylko w WinForms. :)

0

Przykład naprawdę szybko działa, tylko jest jeszcze jeden mały problem. W słowniku znajdują się struktura -> kolumna, wartość. Ta sama kontrola w zależności od kontekstu generuje inne kolumny wraz z wyliczeniem wartości. Mógłbym stworzyć bardzo uniwersalnych kontener na dane tak jak w przykładzie Person, pytanie tylko jak pożenić odpowiednie kolumny z klasą?

0

Windows Phone nie daje dostępu do zwykłych metod Read() i Write(), a potrzebuję odczytać dane z strony www do mojej aplikacji. Dzięki za wstawienie tutoriala, już teraz lepiej mi to przychodzi. Jednak mam jeszcze pytanie czy kod asynchroniczny jest zawsze taki duży pod względem objętościowym? Czy nie ma jakiejś krótszej pod względem objętościowym metody? Po przeanalizowaniu przykłądu i przetestowaniu przykładu zabieram się do przepisywania kodu i dostosowania go do moich potrzeb, ale chcę wiedzieć czy zawsze ten kod musi wyglądać tak samo, jak wiadomo zawsze jest kilka metod rozwiązania problemu?

0 użytkowników online, w tym zalogowanych: 0, gości: 0