Использование 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 – координаты конца диапазона. Номера строк и
колонок отсчитываются от нуля и включают в себя все без исключения строки и
колонки (в том числе скрытые, фиксированные, «замороженные» и т. д.). Пример
применения диапазона уже приводился выше (пример применения стиля к диапазону
ячеек).
Установить данные в ячейке или
получить их оттуда можно с помощью методов
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
– одно или несколько значений перечисления
Значение
|
Описание
|
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 содержит функцию
C#:
public string[] LoadExcelSheetNames(string fileName)
VB.NET:
Public Function LoadExcelSheetNames(fileName
As String) As String()
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)
|
|
None
|
|
Clear
|
|
Sum
|
|
Percent
|
|
Count
|
|
Average
|
|
Max
|
|
Min
|
|
Std
|
|
Var
|
|
StdPop
|
|
VarPop
|
|
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);
}
FlexGrid.Net: Объединение
ячеек.
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;
}
|
|
None
|
|
Free
|
|
RestrictRows
|
|
RestrictCols
|
|
RestrictAll
|
|
FixedOnly
|
|
Spill
|
|
Nodes
|
|
c1FlexGrid1.AllowMerging=AllowMergingEnum.RestrictRows;
c1FlexGrid1.Cols[1].AllowMerging=true;
c1FlexGrid1.Cols[2].AllowMerging=true;
c1FlexGrid1.Cols[3].AllowMerging=true;
FlexGrid.Net:
Пользовательская отрисовка ячеек.
c1FlexGrid1.DrawMode = DrawModeEnum.OwnerDraw;
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;
}
}
Заключение: