Показване на общия ред в DataGridView
Анализ на проблема
Докато разработвах приложение WinForms, се натъкнах на проблема с показването на общия ред (Totals) за цифрови колони в стандартния DataGridView .NET 2.0. Както показва анализ на различни източници и лично търсене, в DataGridView няма такава възможност. В такава ситуация има два варианта:
1. Купете компоненти, където такава функционалност вече е внедрена (DevExpress, ComponentOne, Xceed и др.); 2. Разширете съществуващ DataGridView.
Първият вариант изисква допълнителни финансови разходи (повече от $800), с които клиентът най-вероятно няма да се съгласи. Освен това, ако приложението вече е написано и необходимостта от Totals вече се е появила в процеса, има значителен проблем с интегрирането на нови компоненти с минимални промени в кода, което също не е толкова просто. Затова е необходимо да се добави стандартен DataGridView.
Задачата на пръв поглед не изглежда много трудна, особено след като някой вече може да я реши успешно. Но, странно, търсенето на необходимата информация не даде очакваните резултати. Единственото нещо, което предлагат народните занаятчии, е да добавят ред в края и да покажат необходимата обобщена информация там. Но това решение въвежда и значителен недостатък, например, ако има голям брой редове, които няма да се поберат в DataGridView, и ще трябва да се покаже лента за превъртане. Тогава редът Totals няма да се вижда, тъй като ще бъде последният. В допълнение, позицията на Totals ще се промени, когато се добавят нови редове, което не е напълно правилно.
Ето защо е уместно да се търси по-ефективно решение, най-вече по отношение на ергономичен дисплей, лекота на разработка и модификация.
И така, трябва да е компонент, наследен отSystem.Windows.Forms. DataGridView с необходимите външни настройки и който при актуализиране на DataSource или стойности в клетките ще покаже правилно обобщената информация, независимо от броя на редовете в желания формат.
Разрешаване на проблеми
За разширяване на възможностите на стандартния DataGridView се предлага следният подход. Трябва да разработите контрола, която всъщност ще се намира извън DataGridView. С други думи, да се добави към „децата“ на родителя на самия DataGridView. В същото време той трябва да бъде под формата на низ, чиито колони ще бъдат свързани със съответните колони на DataGridView.
Първото просто решение е за всяка колона, където е необходимо да се покаже Общо, добавете обичайния System.Windows.Forms.Label към „родителя“, който първоначално беше внедрен. Но резултатите от тестовете показаха, че такова внедряване има значителни недостатъци (строго погледнато, "бъгове"), по отношение на необходимостта от промяна на позицията и ширината на колоните, както и използването на хоризонтални и вертикални ленти за превъртане. Не беше възможно да се коригират напълно нововъзникналите затруднения, докато кодът стана много по-сложен. Следователно се предлага програмно да се добави друг DataGridView в събитието ParentChanged, чиито колони ще дублират напълно родителския, като се вземат предвид ширината, позицията, форматът на показване на данни и т.н.
По този начин се решава проблемът с хоризонталното превъртане на реда Total, тъй като в този случай свойството HorizontalScrollingOffset трябва да бъде зададено за TotalDataGridView. Освен това всичко работи правилно при промяна на ширината и позицията на колоните.
След това трябва да маркирате тези колони, за които искате да покажете Общо. За да направим това, създаваме enum:
public enum ShowTotal No=0, Да = 1 >
и задайте свойството Tag за необходимите колони, например
В процеса на добавяне на TotalDataGridView се създава колекцията List _totals, която съдържа колоните, маркирани за общото изчисление, което се извършва по следния начин:
public void CalculateTotals() двойно общо = 0; foreach (колона DataGridViewColumn в _totals) foreach (ред DataGridViewRow в this.Rows) if (!row.IsNewRow && !(row.Cells[column.Index].Value is DBNull)) total += Convert.ToDouble(row.Cells[column.Index]. Стойност); > _totalGr > общо = 0; > _countValueLable.Text = Rows.Count.ToString(); >
Методът CalculateTotals() трябва да бъде извикан при редица събития на DataGridView: OnRowsAdded, OnCellValueChanged, OnDataSourceChanged и неговия "родител": OnLoad. За да промените параметрите на показване в свойствата на дизайнера, е създадена секция „Разширени“, която включва редица настройки: ShowTotals, ShowCount, TotalText, CountText.
И така, разработеният TotalDataGridView изглежда така:
Решавайки проблема с показването на обобщения ред, беше избран най-оптималния вариант, който е разширяване на възможностите на стандартния DataGridView .NET 2.0. Задачата се изпълнява чрез добавяне на дубликат TotalDataGridView с един ред към родителя на "родителя" DataGridView. Това, на първо място, постига правилното показване на реда Total при промяна на лентите за превъртане, позицията и ширината на колоните.