Visual Basic, .NET, ASP, VBScript
 

   
 
Описание для автора не найдено
 
     
   
 

Использование True DBGrid при создании приложений для управления базами данных на Visual Studio.Net (часть 5) – использование FlexGrid.Net.

 

 

О FlexGrid.Net.

 

Тема данной немного выходит за пределы заявленного в самом начале, но раз уже мы рассматриваем «представление данных в табличном виде», то следует рассказать и о FlexGrid.

ComponentOne предоставляет не один, а целых два компонента FlexGrid:

 

              

 

                           Рис 1.

 

Компонент C1FlexGrid – это новый компонент, объектная структура которого полностью переработана под стандарты .NET.

Компонент C1FlexGridClassic – это тоже новый контрол, предназначенный для работы в среде .NET, но он имеет старую объектную модель, унаследованную от ActiveX. В документации говорится, что он предназначен для облегчения перехода на новую платформу. Сам я еще не работал с C1FlexGridClassic (и наверное, не буду, хотя и есть опыт работы с предыдущими версиями), так что все, о чем говорится в статье относится только к C1FlexGrid.

 

Использование FlexGrid.Net. Связанный режим.

 

Опять же, рассказывать о создании формы и размещении на ней C1FlexGrid я не буду.

Вот как выглядит форма с помещенной на ней C1FlexGrid

 

 

                                                               Рис 2.

 

C1FlexGrid может использоваться как в связанном с данными режиме, так и в несвязанном. Как показывает практика чаще используется именно несвязанный режим, и здесь данный контрол оказывается как нельзя кстати (в Windows Forms почему-то ничего подобного вообще нет), но сначала давайте рассмотрим все-таки связанный режим.

Для связи с данными могут применяться любые из предназначенных для этого компоненты (как стандартные, так и компоненты, рассмотренные ранее в данном цикле статей). Кроме того, связать  C1FlexGrid с данными можно и непосредственно с помощью кода.

Разместим на форме компонент C1ExpressTable и свяжем его с данными. Теперь нужно в свойстве DataSource C1FlexGrid установить наш C1ExpressTable. Если все нормально, сразу же произойдет обновление полей таблицы. Что меня удивило, так это отсутствие команды Retrieve Fields в контекстном меню. Обновить поля можно только с помощью кнопки в редакторе полей.

Итак, щелкаем правой кнопкой мыши, и в контекстном меню выбираем Columns Editor.. Запускается редактор колонок:

 

 

                                                               Рис 3.

 

На скриншоте я красным кружком обвел ту самую кнопку обновления полей. Ее так не сразу и заметишь.

Редактор очень похож на аналогичный редактор колонок C1TrueDBGrid, и так же позволяет редактировать параметры колонок в «визуальном» режиме.

Большая часть свойств колонки не вызывает вопросов. Насчет других, необходимо дать некоторые предварительные пояснения.

В отличие от FlexGrid из Visual Basic 6, который позволяет только отображать данные, C1FlexGrid позволяет редактировать их, причем при работе в связанном с данными режиме внесенные изменения автоматически сохраняются. Так вот, по возможностям редактирования C1FlexGrid оставляет далеко позади другие табличные контролы. А в принципе, наше приложение уже можно запускать:

 

 

                                                   Рис 4.

 

Редактирование таблицы

 

Вот теперь давайте поговорим об уникальных возможностях редактирования, предоставляемых C1FlexGrid.

Проще всего встроить в ячейку комбобокс. За это отвечает свойство ComboList (см. Рис 3). Его нужно заполнить значениями комбобокса, разделенными вертикальной чертой:

значение1|значение2|значение3|значение4

 

Все, этого достаточно, чтобы при щелчке по ячейке в выбранной колонке появлялся комбобокс:

 

              

 

                                       Рис 5.

Данные в таком комбобоксе статичны, а на практике часто возникает потребность в их обновлении. Для этого необходимо определить источник для заполнения комбобокса и присвоить его свойству DataMap требуемой колонки. Источник должен реализовывать интерфейс IDistionary. Этот интерфейс определяет структуры данных, состоящих из пар «ключ – значение». При использовании такого источника данных в комбобоксе будет отображаться «значение», а в редактируемую ячейку будет передан «ключ». Примерами структур, реализующих IDistionary могут быть:

 

- Hashtable;

- ListDictionary;

- SortedList.

 

Пример (C#)

 

      //создаем и заполняем Хеш-таблицу

      Hashtable ht=new Hashtable();

      ht.Add(1,"Один");

      ht.Add(10,"Десять");

      ht.Add(100,"Сто");

      ht.Add(1000,"Тысяча");

      //подключаем источник данных к столбцу

c1FlexGrid1.Cols[1].DataMap = ht;

 

Кроме того, в качестве источника данных для комбобокса может служить перечисление:

 

      private enum Towns

      {

            Москва,

            Тула,

            Самара,

            Урюпинск,

}

 

//подключаем источник данных к столбцу

c1FlexGrid1.Cols[1].DataType = typeof(Towns);

 

При использовании перечисления в ячейку будет передаваться то же значение, что и отображается в комбобоксе.

 

Никто не запрещает вам написать свой собственный класс, реализующий IDistionary и использовать его в качестве источника данных для встроенных в C1FlexGrid комбобоксов.

 

C1FlexGrid автоматически, по типу поля изменяет способ его редактирования. Так, например, для полей Дата/Время автоматически появляется встроенный календарь:

 

              

 

                                       Рис 6.

 

В логических полях автоматически ставятся флажки. Если флажки вас не устраивают, их можно заменить парой строковых значений или парой картинок:

 

c1FlexGrid1.Cols["Pay"].Format = "Оплачено;Не оплачено";

 

 

Свойство Format отвечает за форматирование числовых значений и значений Даты/Времени. Возможные значения:

С или с – денежный формат;

E или e – экспоненциальный формат;

F или f – формат с плавающей точкой;

N или n – целочисленный формат;

P или p – процентный формат

 

d – короткий формат даты;

D – длинный формат даты;

t – короткий формат времени;

T – длинный формат времени

 

Данное свойство устанавливает лишь «общие форматы». Для большего ограничения вводимых данных служит поле EditMask, где можно точно задать маску ввода.

Предположим, что параметры редактирования по умолчанию вас не устраивают. C1FlexGrid позволяет использовать для редактирования ячеек любой внешний редактор. В качестве такого редактора может выступать либо контрол, либо другая форма, либо другая программа (можете хоть Word или Excel запустить для этого).

Для примера я взял компонент C1DataEdit от той же ComponentOne. Разместим его в произвольном месте формы и сделаем изначально невидимым. Теперь достаточно свойство Editor колонки (типа Дата/Время) установить в  c1DataEdit1. Все, можно запускать. Вы увидите, что вместо стандартного календаря в данном поле будет вызываться c1DataEdit:

 

                          

 

                                                   Рис 7.

 

Более тонко редактирование можно настроить программно. При использовании встроенных редакторов используется свойство EditOptions, которое принимает набор из оного или нескольких флагов редактирования (EditFlags)

 

None

Сбрасывает все опции редактирования

AutoSearch

Для текстовых полей (в том числе со встроенным комбобоксом) включает режим «автозаполнения»

CycleOnDoubleClick

При двойном щелчке по выбранному полю в нем циклически перебираются предопределенные значения (для поля должен быть заполнен список ComboList

MultiCheck

Применяется для логических полей. В этом режиме при изменении значения одного из чекбоксов изменяется значение и всех остальных.

All

Установлены все флаги (значение по умолчанию)

 

Довольно часто требуется для редактирования значения ячейки вызвать, например, диалоговое окно. Для этого следует:

 

1.      Установить свойство ComboList в «…» (три точки).

Это приведет к тому, что при получении фокуса ячейкой данного столбца в ней будет отображаться кнопка (с тремя точками)

 

                                      

 

                                                   Рис. 8

 

2.      Перехватить событие CellButtonClick, и в его обработчике выполнить требуемые действия.

 

Теперь еще одно. По умолчанию редактируется содержимое ячейки (чаще всего текст), но бывают ситуации, когда нужно изменить и другие параметры ячейки, например цвет или размер. Приведенный подход позволяет сделать это. Давайте покажем на примере, как можно изменить цвет фона текущей ячейки.

В обработчике CellButtonClick пишем следующий код:

 

private void c1FlexGrid1_CellButtonClick(object sender, RowColEventArgs e)

{

      // создаем диалог выбора цвета

      ColorDialog  clrDlg = new ColorDialog();

      // инициализируем диалог

      if (clrDlg.ShowDialog() == DialogResult.OK)

      {

            //изменяем цвет фона текущей ячейки

            CellRange rg = c1FlexGrid1.GetCellRange(e.Row,e.Col);

            rg.StyleNew.BackColor=clrDlg.Color;

}

}

 

Теперь нажатие кнопки в редактируемой ячейке вызовет стандартный диалог выбора цвета:

 

                                                  

                                                   Рис. 9

После того, как пользователь выберет цвет и щелкнет кнопку OK диалога, фон ячейки окрасится в выбранный цвет:

 

                          

 

                                                   Рис. 10

 

Как и C1True DBGrid C1FlexGrid предоставляет программисту возможность перехвата событий редактирования ячейки. Но у C1FlexGrid набор событий другой. Поэтому рассмотрим их более подробно:

 

BeforeEdit – это событие возникает, как только редактируемая ячейка получает фокус. Событие имеет параметр Cancel, установка которого в True отменяет редактирование. Перехватив это событие, можно например, проверить актуальность списка ComboBox и, при необходимости, обновить его.

 

StartEdit – генерируется, когда фокус находится в редактируемой ячейке, и пользователь нажал клавишу или кнопку мыши начиная редактирование. Именно перехватив это событие программист может «подсунуть» пользователю любой другой редактор вместо стандартного.

 

SetupEditor – генерируется в момент, когда закончилась загрузка редактора (встроенного или внешнего). Перехватив это событие, программист получает в свое распоряжение сам редактор.

 

ValidateEdit – генерируется в момент, когда новое значение передано из редактора в ячейку, но сам редактор еще не деактивирован. Стандартное применение – проверка корректности вводимого значения.

 

AfterEdit – возникает уже после деактивации и выгрузки редактора.

 

Действия пользователя, начинающего или заканчивающего редактирование ячейки можно вызывать и программно с помощью методов StartEditing и FinishEditing.

 

Использование стилей таблицы

 

Как и в C1True DBGrid, внешний вид таблицы C1FlexGrid формируется с использованием стилей.

Для доступа к списку стилей следует в контекстном меню выбрать пункт Edit Styles… Откроется соответствующее диалоговое окно:

 

 

                                                   Рис 11

 

Здесь уже имеется около полутора десятков встроенных (Built-in) стилей. Кроме того, пользователь может создать произвольное число своих, пользовательских (Custom) стилей. Пользовательские стили создаются на основе стиля Normal. Встроенные стили также могут быть отредактированы, но их нельзя удалять.

Кроме стилей имеется несколько готовых форматов таблицы, которые тоже можно использовать. Для этого следует нажать кнопку AutoFormat…

 

 

                                                   Рис. 12

 

Стили, конечно же, можно применять и программно. В отличие от C1True DBGrid, где стили можно применять к

- таблице;

- колонке;

- строке;

- ячейке,

C1FlexGrid кроме того позволяет применить стиль к диапазону ячеек. Обращение к стилям из кода производится по имени.

 

      CellRange rg = c1FlexGrid1.GetCellRange(3, 3, 10, 10);

rg.Style = c1FlexGrid1.Styles["EmptyArea"];

 

Смотрим результат:

 

 

                                                               Рис. 13

Однако параметры стилей (как встроенных, так и пользовательских) нельзя изменять из кода. Для динамического изменения стиля ячейки служит параметр StyleNew диапазона ячеек. (Смотрите пример изменения цвета фона ячейки).

 

Использование «закрепленных» ячеек

 

C1FlexGrid позволяет производить «закрепление» (или «замораживание» в дословном переводе) ячеек. Такие ячейки остаются на месте при пользовании полосами прокрутки.

Настроить закрепление ячеек можно только программно. Для этого необходимо:

 

1.                     Установить значение свойства AllowFreezing таблицы. Это свойство принимает одно из значений перечисления AllowFreezingEnum. Его возможные значения:

              

               - Both;

               - Columns;

               - Rows;

               - None.

 

2.                     Указать количество закрепленных столбцов и/или строк.

 

            c1FlexGrid1.AllowFreezing=AllowFreezingEnum.Both;

            c1FlexGrid1.Cols.Frozen=2;

       c1FlexGrid1.Rows.Frozen=3;

 

 

                                                               Рис.14

 

По умолчанию C1FlexGrid применяет к закрепленным ячейкам стиль Frozen, хотя программист, естественно, может назначить любой другой.

 

Следует понимать отличие «замороженных» ячеек и «фиксированных» ячеек, которые были уже у FlexGrid в VB 6. Давайте вставим в обработчик загрузки формы следующий код:

 

c1FlexGrid1.Rows.Fixed=3;

 

Запускаем…

 

 

                                                               Рис. 15

 

«Замороженные» ячейки, в отличие от «фиксированных» заполняются данными в связанном режиме. Программно, из кода доступны все ячейки без исключения.

 

Использование FlexGrid.Net. Несвязанный режим.

 

Конечно же, «классика» программирования предусматривает использование базы данных. Но на практике довольно часто встречаются ситуации, когда информацию надо собирать из нескольких разных источников, да еще и обрабатывать по сложному алгоритму. Вот здесь и приходит на помощь несвязанный режим, который дает программисту полную свободу отображения данных в табличном виде.

 

Большинство элементов таблицы собраны в коллекции. С точки зрения программиста FlexGrid.Net имеет: коллекцию строк, коллекцию колонок, коллекцию ячеек, коллекцию заголовков, коллекцию фиксированных ячеек, и т. д. Следовательно, ко всем этим элементам применимы стандартные методы работы с коллекциями. Например, к столбцам и строкам можно обращаться как по индексу, так и по имени, можно применять оператор foreach, и т. д.

Кроме того, важнейшим элементом FlexGrid.Net является объект CellRange – диапазон ячеек, представляющий собой «подколлекцию» ячеек.

Определяется диапазон ячеек с помощью метода GetCellRange. Ввиду исключительной важности приведу полностью синтаксис этого метода:

 

C#:

public CellRange GetCellRange(int row, int col)

public CellRange GetCellRange(int row1, int col1, int row2, int col2)

 

VB.NET:

Public Function GetCellRange(row As Integer, col As Integer) As CellRange

Public Function GetCellRange(row1 As Integer, col1 As Integer, row2 As Integer, col2 As Integer) As CellRange

 

Первый вариант метода (как для C#, так и для VB.NET) определяет диапазон, состоящий из одной единственной ячейки. row – номер строки, col – номер колонки. Второй вариант метода определяет диапазон в виде прямоугольной области внутри таблицы. row1 и col1 – координаты начала диапазона, row2 и col2 – координаты конца диапазона. Номера строк и колонок отсчитываются от нуля и включают в себя все без исключения строки и колонки (в том числе скрытые, фиксированные, «замороженные» и т. д.). Пример применения диапазона уже приводился выше (пример применения стиля к диапазону ячеек).

Установить данные в ячейке или получить их оттуда можно с помощью методов SetData и GetData соответственно. Эти методы имеют массу перегруженных вариантов:

 

C#:

public Boolean SetData(int row, String colName, Object data)

public Boolean SetData(int row, String colName, Object data, Boolean coerce)

public Boolean SetData(CellRange rg, Object data)

public Boolean SetData(int row, int col, Object data)

public Boolean SetData(CellRange rg, Object data, Boolean coerce)

public Boolean SetData(int row, int col, Object data, Boolean coerce)

 

VB.NET:

Public Function SetData(row As Integer, colName As String, data As Object) As Boolean

Public Function SetData(row As Integer, colName As String, data As Object, coerce As Boolean) As Boolean

Public Function SetData(rg As CellRange, data As Object) As Boolean

Public Function SetData(rg As CellRange, data As Object, coerce As Boolean) As Boolean

Public Function SetData(row As Integer, col As Integer, data As Object) As Boolean

Public Function SetData(row As Integer, col As Integer, data As Object, coerce As Boolean) As Boolean

C#:

public Object GetData(int row, int col)

public Object GetData(int row, String colName)

 

VB.NET:

Public Function GetData(row As Integer, col As Integer) As Object

Public Function GetData(row As Integer, colName As String) As Object

 

Обратите внимание: все перечисленные методы работают с данными типа Object. При установке данных FlexGrid.Net автоматически преобразует их соответственно типу данных колонки. Возвращаемое значение также имеет тип соответствующей колонки. Часть методов SetData в качестве одного из аргументов принимают булеву переменную coerce. Ее значение определяет поведение FlexGrid.Net при преобразовании типов. Если переменная установлена в true (значение по умолчанию) то при ошибке преобразования данных генерируется событие GridError а в ячейку помещаются оригинальные данные. Если переменная установлена в false, ошибка игнорируется.

То, что в ячейки можно поместить значения типа Object полностью развязывает руки программисту. Можно, например, написать свой собственный класс, содержащий любые данные, и переопределить его метод ToString(). Именно строка, возвращаемая методом ToString() и будет отображаться в ячейке.

Теперь представьте себе: имеется класс, содержащий звуковой файл с музыкой. Метод ToString возвращает название композиции. Различные экземпляры класса распихиваем по ячейкам. Теперь по двойному щелчку на ячейке извлекаем файл и запускаем его на воспроизведение. Правда здорово?

 

Пишем код:

 

c1FlexGrid1.SetData(5,3,"Текущая ячейка");

 

Смотрим:

           

                                       Рис 17.

 

Точно такой же результат можно получить, используя и следующий код:

 

c1FlexGrid1[5,3]="Текущая ячейка";

 

Здесь реализован доступ к ячейке как к элементу коллекции.

 

Следующий способ заполнения таблицы в несвязанном режиме – использование строки. Я уже писал, что строки собраны в коллекцию, так вот, эта коллекция имеет ряд  дополнительных методов, упрощающих заполнение таблицы. Практика показывает, что именно этот способ заполнения FlexGrid.Net является самым удобным для несвязанного режима..

Метод, добавляющий строки, содержится непосредственно у FlexGrid.Net. Полный синтаксис:

 

C#:

public Row AddItem(String item)

public Row AddItem(String item, Int index)

public Row AddItem(object[] items)

public Row AddItem(object[] items, Int rowIndex, Int colIndex)

 

VB.NET:

Public Function AddItem(item As String) As Row

Public Function AddItem(item As String, index As Integer) As Row

Public Function AddItem(items As Object()) As Row

Public Function AddItem(items As Object(), rowIndex As Integer, colIndex As Integer) As Row

В качестве основного аргумента метод принимает либо специальным образом отформатированную строку, либо массив объектов.

 

Строка – аргумент метода AddItem представляет собой последовательность значений, разделенных специальным символом-разделителем. Символ-разделитель задается свойством ClipSeparators. В качестве символа-разделителя можно использовать любые символы кодовой таблицы, а также специальные последовательности (типа \n или \t).

 

Пример кода:

 

c1FlexGrid1.ClipSeparators = "|;";

c1FlexGrid1.AddItem("колонка 0|колонка 1|колонка 2",0);

 

Запускаем:

 

              

 

                                       Рис 18.

 

Точно такого же результата можно добиться и с помощью следующего кода:

 

object[] items = {"колонка 0","колонка 1","колонка 2"};

c1FlexGrid1.AddItem(items,0, 0);

 

Заполнение FlexGrid.Net данными из нереляционных источников и сохранение содержимого таблицы на диске.

 

Помимо связи с классическими базами данных FlexGrid.Net позволяет заполнять таблицу из двух типов нереляционных источников: текстовых файлов и таблиц Excel. Также возможно и сохранение содержимого таблицы в виде текстового файла или таблицы Excel. Для этого служат методы LoadGrid и SaveGrid соответственно. Эти методы имеют по несколько перегруженных форматов:

 

Метод LoadGrid:

C#:

public void LoadGrid(string fileName, FileFormatEnum format)

public void LoadGrid(string fileName, FileFormatEnum format, FileFlags flags)

public void LoadGrid(string fileName, FileFormatEnum format, FileFlags flags, Encoding encoding)

 

VB.NET

Public Sub LoadGrid(fileName As String, format As FileFormatEnum)

Public Sub LoadGrid(fileName As String, format As FileFormatEnum, flags As FileFlags)

Public Sub LoadGrid(fileName As String, format As FileFormatEnum, flags As FileFlags, encoding As Encoding)

 

Метод SaveGrid:

C#:

public void SaveGrid(String fileName, FileFormatEnum format)

public void SaveGrid(String fileName, FileFormatEnum format, FileFlags flags)

public void SaveGrid(String fileName, FileFormatEnum format, FileFlags flags, Encoding encoding)

VB.NET:

Public Sub SaveGrid(fileName As String, format As FileFormatEnum)

Public Sub SaveGrid(fileName As String, format As FileFormatEnum, flags As FileFlags)

Public Sub SaveGrid(fileName As String, format As FileFormatEnum, flags As FileFlags, encoding As Encoding)

 

Здесь     fileName – имя файла (включая путь);

               format – значение перечисления FileFormatEnum, определяющий формат                       входного или выходного файла.

 

Значение

Описание

TextComma

Значения ячеек разделяются запятыми.

TextTab

Значения ячеек разделяются символом табуляции.

TextCustom

Символ – разделитель определяется программистом. Для этого служит свойство  ClipSeparators

Excel

Таблица сохраняется в виде файла Excel.

 

               flags – одно или несколько значений перечисления FileFlags:

 

Значение

Описание

None

Отсутствие флагов (значение по умолчанию)

IncludeFixedCells

Включить в вывод (ввод) фиксированные ячейки.

VisibleOnly

Использовать только видимые ячейки (не поддерживается файлами Excel)

SelectedRowsOnly

Использовать только выделенные ячейки (не поддерживается файлами Excel)

 

               encoding – экземпляр класса System.Text.Encoding, определяющий                                   кодировку выходного файла (ASCII, Unicode, UTF-7, UTF-8). По                              умолчанию используется значение Encoding.ASCII. Этот параметр                                игнорируется при работе с файлами Excel.

 

Добавим на форму кнопку «Экспорт»

 

 

                                                               Рис 18.

 

В обработчик нажатия кнопки вставляем следующий код:

 

c1FlexGrid1.SaveGrid(@"C:\GridTest.txt",FileFormatEnum.TextComma);

 

Полученный файл можно просмотреть, например, с помощью Блокнота:

 

                                                  

                                                   Рис 19.

 

При сохранении таблицы методом SaveGrid в файл Excel будет создан xls – файл, содержащий единственный рабочий лист, на котором и будут размещены данные. Аналогично, при загрузке таблицы из xls – файла, будут импортированы данные только первого рабочего листа.

Если нужно специфицировать рабочий лист, следует использовать методы SaveExcel и LoadExcel.

 

C#:

public void SaveExcel(string fileName)

public void SaveExcel(string fileName, string sheetName)

public void SaveExcel(string fileName, string sheetName, FileFlags flags)

 

VB.NET:

Public Sub SaveExcel(fileName As String)

Public Sub SaveExcel(fileName As String, sheetName As String)

Public Sub SaveExcel(fileName As String, sheetName As String, flags As FileFlags)

 

Здесь sheetName – имя рабочего листа, а аргумент flags принимает те же значения, что и для методов SaveGrid и LoadGrid.

Для облегчения работы с xls – файлами FlexGrid.Net содержит функцию LoadExcelSheetNames, которая возвращает массив строк, содержащих имена рабочих листов Excel в выбранном файле. Ее синтаксис:

 

C#:

public string[] LoadExcelSheetNames(string fileName)

 

VB.NET:

Public Function LoadExcelSheetNames(fileName As String) As String()

 

FlexGrid.Net: построение древовидных структур и вычисление промежуточных и общих итогов.

 

Очень интересной особенностью контрола FlexGrid.Net является то, что он позволяет представлять данные не только в виде таблицы, но и в виде древовидной структуры, а также проводить вычисления с использованием агрегатных функций.

Для этого служит метод Subtotal:

 

C#:

public void Subtotal(AggregateEnum aggType)

public void Subtotal(AggregateEnum aggType, int level, int groupOn, int totalOn)

public void Subtotal(AggregateEnum aggType, int level, int groupOn, int totalOn, String caption)

public void Subtotal (AggregateEnum aggType, int level, int groupFrom, int groupTo, int totalOn, String caption)

 

VB.NET

Public Sub SubtotalaggType As AggregateEnum)

Public Sub Subtotal(aggType As AggregateEnum, level As Integer, groupOn As Integer, totalOn As Integer)

Public Sub Subtotal(aggType As AggregateEnum, level As Integer, groupFrom As Integer, groupTo As Integer, totalOn As Integer, caption As String)

Public Sub Subtotal(aggType AggregateEnum, level As Integer, groupOn As Integer, totalOn As Integer, caption As String)

 

AggregateEnum – перечисление, определяющее вид используемой агрегатной функции:

 

Тип функции

Описание:

None

Отсутствие агрегатной функции. Данная установка используется для создания узла дерева без какого – либо агрегирования.

Clear

Стирает все предыдущие вычисления агрегатных функций. Необходимо использовать перед сменой какой-либо функции.

Sum

Возвращает сумму значений ячеек выбранного диапазона. Ячейки, имеющие значение null игнорируются.

Percent

Возвращает процентное значение для подгруппы по отношению к общему итогу.

Count

Возвращает количество ячеек выбранного диапазона.  Ячейки, имеющие значение null игнорируются.

Average

Возвращает среднее значение выбранного диапазона. Ячейки, имеющие значение null игнорируются.

Max

Возвращает максимальное значение выбранного диапазона.

Min

Возвращает минимальное значение диапазона

Std

Возвращает значение стандартного отклонения в диапазоне ячеек. Формула базируется на n-1 выборках)

Var

Возвращает значение простого отклонения в диапазоне ячеек. Формула базируется на n-1 выборках)

StdPop

Возвращает значение стандартного отклонения в диапазоне ячеек. Формула базируется на n выборках)

VarPop

Возвращает значение простого отклонения в диапазоне ячеек. Формула базируется на n выборках)

 

level – уровень вычисления промежуточных итогов. Может принимать и отрицательные значения. В этом случае соответствующие узлы на дереве не отображаются.

 

groupOn – индекс столбца, по значению которого будет производится группировка.

 

groupFrom, groupTo – диапазон колонок, по значениям которых будет производится группировка. В этом случае сканируются значения всех столбцов указанного диапазона и каждый раз, как только хотя бы в одном из них поменялось значение, создается новая подгруппа.

 

totalOn – индекс столбца, по значению которого рассчитывается агрегатная функция. Данный столбец должен содержать числовые значения.

 

caption – текст, который используется в качестве заголовка строки, содержащей результаты работы агрегатной функции. В тексте заголовка может использоваться заглушка {0}, вместо которой в таблице отображается имя данных, по которым производится группировка.

 

Приведем пример. В базе данных Northwind подходящей таблицы не нашлось, я использовал представление, которое используется в примерах к FlexGrid.Net. Вот его SQL – выражение:

 

SELECT Employees.LastName, Orders.ShipCountry, Categories.CategoryName, Products.ProductName, Orders.OrderDate, [Quantity]*[Products].[UnitPrice] AS [Sale Amount] FROM (Categories INNER JOIN Products ON Categories.CategoryID = Products.CategoryID) INNER JOIN ((Employees INNER JOIN Orders ON Employees.EmployeeID = Orders.EmployeeID) INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID) ON Products.ProductID = [Order Details].ProductID ORDER BY Employees.LastName, Orders.ShipCountry, Categories.CategoryName

 

Теперь в процедуре загрузки формы пишем:

 

private void Form1_Load(object sender, System.EventArgs e)

{

      //прячем фиксированную колонку

      c1FlexGrid1.Cols[0].Width =0;

      //указываем, что дерево будет находиться в первой колонке

      c1FlexGrid1.Tree.Column = 1;

      //устанавливаем стили итоговых строк

      CellStyle s = c1FlexGrid1.Styles[CellStyleEnum.GrandTotal];

      s.BackColor = Color.Black;

      s.ForeColor = Color.White;

      s = c1FlexGrid1.Styles[CellStyleEnum.Subtotal0];

      s.BackColor = Color.Salmon;

      s.ForeColor = Color.Black;

      s = c1FlexGrid1.Styles[CellStyleEnum.Subtotal1];

      s.BackColor = Color.Pink;

      s.ForeColor = Color.Black;

      s = c1FlexGrid1.Styles[CellStyleEnum.Subtotal2];

      s.BackColor = Color.LightYellow;

      s.ForeColor = Color.Black;

      //указываем строку, по которой будет осуществляться суммирование

      int totalOn = c1FlexGrid1.Cols[6].SafeIndex;

      //заголовки итоговых строк

      string  caption = "Итоги по {0}";

      //рассчитываем три уровня итогов

      c1FlexGrid1.Subtotal(AggregateEnum.Sum, 0, 1, totalOn, caption);

      c1FlexGrid1.Subtotal(AggregateEnum.Sum, 1, 2, totalOn, caption);

      c1FlexGrid1.Subtotal(AggregateEnum.Sum, 2, 3, totalOn, caption);

      //разворачиваем дерево на два уровня

      c1FlexGrid1.Tree.Show(2);

}

 

Смотрим, что получилось:

 

 

                                                               Рис 20.

 

И идем к начальнику требовать повышения жалования…

 

Кроме того, FlexGrid.Net умеет отображать «дерево» и в несвязанном режиме. Для этого необходимо:

 

1.      С помощью метода AddItem добавляем строку;

2.      Устанавливаем свойство Row[индекс].IsNode равным true;

3.      Получаем объект Node каждой строки, и устанавливаем значение его свойства Level.

 

В таком режиме FlexGrid.Net фактически повторяет TreeView, поэтому дальше я его рассматривать не буду.

 

FlexGrid.Net: Объединение ячеек.

 

Возможность объединения ячеек, содержащих одинаковые данные, появилась еще у FlexGrid в комплекте VB5. У FlexGrid от ComponentOne эти возможности гораздо шире, и их количество увеличивалось от версии к версии.

 

1.     Объединение ячеек заголовка.

 

Если обычно объединение ячеек основано на равенстве находящихся в них значений, то FlexGrid.Net позволяет произвести объединение «от обратного»:

- сформировать объект CellRange;

- объединить ячейки в этом объекте;

- занести данные в объединенную ячейку.

 

Такая технология обычно используется для оформления заголовков.

 

Вводим код в событие Load:

 

private void Form1_Load(object sender, System.EventArgs e)

{

      c1FlexGrid1.Cols.Count = 9;

      c1FlexGrid1.Rows.Fixed = 2;

      c1FlexGrid1.AllowMerging = AllowMergingEnum.FixedOnly;

      c1FlexGrid1.Rows[0].AllowMerging = true;

      CellRange rng = c1FlexGrid1.GetCellRange(0, 1, 0, 4);

      rng.Data = "Дебет";

      rng = c1FlexGrid1.GetCellRange(0, 5, 0, 8);

      rng.Data = "Кредит";

      for(int i = 1 ; i <= 4; i++)

      {

            c1FlexGrid1[1, i] = "Клиент " + i;

            c1FlexGrid1[1, i + 4] = "Клиент " + i;

      }

      c1FlexGrid1.Cols[0].AllowMerging = true;

      rng = c1FlexGrid1.GetCellRange(0, 0, 1, 0);

      rng.Data = "Баланс";

      c1FlexGrid1.Styles.Fixed.TextAlign = TextAlignEnum.CenterCenter;

}

 

Смотрим:

 

 

                                                               Рис 21.

 

2.     Объединение ячеек с данными.

 

За объединение ячеек отвечает свойство AllowMerging. Таким свойством обладают как весь объект FlexGrid.Net, так и коллекции Rows и Columns. Однако это свойство может принимать различные значения для различных объектов.

 

Для объекта FlexGrid свойство AllowMerging может принимать значения из перечисления AllowMergingEnum. Его значения:

 

Значение

Описание

None

Ячейки не объединяются

Free

Объединяются все ячейки, содержащие совпадающие данные

RestrictRows

Объединяются только строки

RestrictCols

Объединяются только столбцы

RestrictAll

Объединение происходит в прямоугольной области, содержащей совпадающие данные.

FixedOnly

Объединяются только фиксированные строки и столбцы.

Spill

Используется для отображения длинных строк, которые не помещаются в ячейке. В этом режиме если ячейка получает фокус, данные разворачиваются во всю длину, «затирая» значения соседних ячеек.

Nodes

То же самое, но используется при отображении длинных названий узлов «дерева».

 

Для строк и столбцов свойство AllowMerging может принимать значения true и false, соответственно разрешая или запрещая объединение данной строки/колонки.

 

Записываем в процедуру загрузки формы код:

 

c1FlexGrid1.AllowMerging=AllowMergingEnum.RestrictRows;

c1FlexGrid1.Cols[1].AllowMerging=true;

c1FlexGrid1.Cols[2].AllowMerging=true;

c1FlexGrid1.Cols[3].AllowMerging=true;

 

Смотрим:

 

 

                         Рис 22.

 

Для нормального объединения ячеек необходимо, чтобы данные были предварительно отсортированы.

 

FlexGrid.Net: Пользовательская отрисовка ячеек.

 

Хочется поблагодарить создателей FlexGrid.Net, как и создателей других контролов, которые предоставляют конечному пользователю режим OwnerDraw. Это позволяет программисту, если, по его мнению, стандартных возможностей не хватает, сделать отрисовку самому.

Для пользовательской отрисовки FlexGrid.Net необходимо:

1.      Установить свойство DrawMode равным  OwnerDraw;

2.      Перехватить событие OwnerDrawCell, и в его обработчик вставить соответствующий код.

Давайте прорисуем фон ячейки градиентной кистью:

 

В обработчик загрузки формы добавляем код:

 

c1FlexGrid1.DrawMode = DrawModeEnum.OwnerDraw;

 

Теперь перехватываем событие OwnerDrawCell:

 

private void c1FlexGrid1_OwnerDrawCell(object sender, C1.Win.C1FlexGrid.OwnerDrawCellEventArgs e)

{

      //подготавливаем градиентную кисть

      LinearGradientBrush m_GradientBrush = new       LinearGradientBrush(ClientRectangle, Color.Red, Color.Blue, 45);

      //закрашиваем выделенную область

      if (c1FlexGrid1.Selection.Contains(e.Row, e.Col))

      {

            //закрашивать будем фон

            e.Graphics.FillRectangle(m_GradientBrush, e.Bounds);

            //теперь позволим таблице самостоятельно отрисовать содержимое

            e.DrawCell(DrawCellFlags.Content);

            //создаем "отметку" что ячейка уже перерисована

            e.Handled = true;

      }

}

 

Теперь можно посмотреть, что получилось:

 

 

                                                               Рис 23.

 

Заключение:

 

Буду заканчивать. Конечно же, я рассмотрел не все возможности FlexGrid.Net. Так, например, можно распечатать содержимое таблицы, напрямую работать с xml, и т. д. Надеюсь что читатель понял место FlexGrid.Net в деле представления данных.

 

Следующую статью я планирую сделать последней в цикле. Это должен быть сборник из описаний оставшихся возможностей С1 и практических советов. Так что не прощаюсь.

 

 

 
     

   
   
     
  VBNet рекомендует