4. Привязка объектов контроля к источникам данных

Поддержка поиска в IBindingList

для эффективного поиска обычно нужно

Последней категорией функций, описываемых интерфейсом IBindingList, Является поиск. Для эффективного поиска обычно нужно как-то индексировать коллекцию. Свойство SupportsSearching Указывает, поддерживает ли коллекция вообще поиск. Если оно возвращает true, вы сможете безопасно вызывать метод Find С дескриптором для свойства, в котором вы хотите искать сопоставление, и объектной ссылкой, содержащей сопоставляемое значение. Если вы реализуете коллекцию, которая поддерживает сортировку и в которой будут находиться большие объемы данных, то для большей эффективности операций поиска вам, возможно, потребуется поддерживать также индексацию данных. Если коллекция поддерживает индексацию, вы можете вызывать метод Addindex Чтобы дать коллекции указание организовать на некотором свойстве индекс, и метод Removelndex, Чтобы удалить ранее добавленный индекс. Например, в конец метода Main На листинге 7.1 можно было бы добавить следующий код, выполняющий поиск некоторого элемента с использованием индексации для ускорения поиска : Реализация на пустом месте коллекции, поддерживающей IBindingList, Требует огромной работы, причем по большей части это кодирование обычных ориентированных на коллекцию функций вроде добавления элементов, удаления элементов, запуска событий ListChanged При изменении коллекции или ее элементов и т. д. До появления. NET 2.0 было мало вариантов, позволяющих уклониться этой работы. Однако класс BindingList В. NET 2.0 значительно упрощает дело, и мы будем подробно исследовать его в главе 9.

Встроенные ячейки заголовка

служат указанием на то что

Ячейки заголовка являются ячейками, отображаемыми вдоль верхней и левой сторон сетки. Они показывают контекст, т. е. служат указанием на то, что именно содержится в ячейках сетки. Ячейки заголовков столбцов имеют тип DataGridviewColumnHeaderCell, а их текст показывает содержание ячеек столбца. Если столбец поддерживает сортировку, ячейка содержит направленный вверх или вниз треугольник; пользователь может сортировать столбец, щелкнув на его заголовке. Обычно текст заголовка устанавливается через свойство HeaderText столбца, либо явным образом в программном коде, либо неявно посредством привязки данных, организованной в соответствии со схемой данных. Вы можете также обращаться к заголовочной ячейке непосредственно через свойство столбца Header — Cell, используя его свойство Value для установки отображаемого текста. Заголовочные ячейки строк имеют тип DataGridViewRowHeaderCell. Они отмечают выбор строки значком треугольника, режим редактирования — значком карандаша, а новую строку — значком звездочки. Заголовочные ячейки строк могут отображать при этом и текст; Вы устанавливаете свойство Value ячейки строковым значением, обращаясь к свойству HeaderCell строки. Заголовки как столбцов, так и строк можно дополнительно настаивать, предусмотрев специальную прорисовку, для чего потребуется обрабатывать событие CellPaint сетки. Заметьте, что если вы осуществляете специальную прорисовку, то сами должны производить все рисование заголовочной ячейки, после чего в свойстве Handled аргумента события Этот код прежде всего проверяет, не является ли индекс рисуемого столбца меньшим нуля; это указывает на то, что прорисовывается заголовок строки. Индекс столбца для заголовков строк равен — 1, и индекс строки для заголовков столбцов также равен — 1. Этими значениями нельзя индексировать коллекцию Cells строки, но можно пользоваться ими в обработчике CellPainting как флагом, позволяющим выяснить, что прорисовывается заголовок.

Кроме того, можно установить в свойстве CellHeader экземпляр класса, производного от DataGridViewCell, и тогда при отображении ячеек заголовка будет использоваться этот тип ячейки. Вы можете определить свой собственный производный класс и выполнять в нем любого рода рисование, форматирование или установку стилей.

Слияние данных из нескольких наборов данных

вашим первым побуждением возможно было

Класс DataSet Поддерживает пару способов перемещения данных между различными наборами данных. Вашим первым побуждением, возможно, было бы просто получить ссылку DataRow Из одного набора данных, возможно, от операции Select Или при итерации таблицы, а затем добавить ее к таблице в другом наборе данных. К сожалению, такое не допускается, и будет выброшено исключение, когда строка данных добавляется к таблице, она становится частью этой таблицы и не может принадлежать одновременно более чем одной таблице. Только строка, которая была создана методом DataTable .NewRow, Может быть добавлена к этой таблице методом Add Коллекции Row Таблицы. Так как же переместить строку или набор строк, принадлежащих одному набору данных, в другой набор данных? Одним способом является использование метода Merge. Поведение этого метода может стать довольно сложным, поскольку он имеет ряд перегрузок, и оно зависит от того, в каком состоянии Находятся строки в наборе данных, откуда они поступают, и имеются ли соответствующие им строки в наборе данных, куда они вливаются. Для простых случаев, однако, все оказывается довольно прямолинейным. Рассмотрим ситуацию, когда у вас есть таблица Customers в одном наборе данных и таблица Orders в другом. Вы хотите, чтобы обе таблицы оказались в одном наборе данных, чтобы вы могли создать родительско-дочер — нее отношение между ними, определяемое внешним ключом CustomerlD, Существующим в таблице Orders. Для этого вы просто вызываете Merge На наборе данных, содержащем таблицу Customers, передав набор данных Orders. Метод Merge Создаст таблицу Orders в наборе данных Customers и скопирует в нее все строки из набора данных Orders. Вы можете затем конструировать отношение между двумя таблицами, как показано ниже: Если вы хотите добавить строку из таблицы в одном наборе данных в ту же самую таблицу в другом наборе данных с состоянием строки Added, Вы можете передать свойство ItemArray Строки-источника перегрузке метода Add Коллекции Rows Таблицы-приемника. Это перенесет значения ячеек как массив объектов в целевую таблицу, создав в ней новую строку, в которой они будут содержаться. Если вы хотите добавить строку из исходной таблицы в целевую и сохранить ее состояние, вы можете использовать метод ImportRow Класса DataTable. Следующий код показывает оба этих подхода:

Определение специального типа столбца

если бы вы собирались использовать

Итак, у нас есть специальный класс ячейки, который можно использовать в сетке, но желательно еще иметь специальный класс столбца, который содержал бы ячейки StatusCell И мог использоваться для организации сетки и привязки данных. Если бы вы собирались использовать специальный тип ячейки исключительно программным способом, можно было бы просто конструировать экземпляр базового класса DataGridViewColumn, Передав конструктору класса экземпляр StatusCell, Который будет уста-новлен в качестве шаблона CellTempiate Для столбца. Однако такой подход не позволит использовать для спецификации привязанного или несвязанного столбца ячеек StatusCells Редакторы столбцов Visual Studio, показанные на рис. 6.4 и 6.5. Для поддержки этого нужно реализовать специальный тип столбца, который будет распознаваться конструктором. Раз вы реализуете свой собственный тип столбца, в нем можно предусмотреть способ задания того, каким по умолчанию должно быть значение Statuslmage Для добавляемых новых строк. Реализация класса StatusColumn Показана в листинге 6.5.

Из реализации StatusColumn Можно видеть, что прежде всего нужно произвести свой класс от DataGridViewColumn. Затем вы реализуете конструктор по умолчанию, который передает экземпляр вашего специального класса ячейки конструктору базового класса. Тем самым в свойстве CellTempiate Базового класса устанавливается данный тип ячейки, который становится типом ячеек для любых строк, добавляемых к сетке, содержащей ваш тип столбца. Далее класс определяет открытое свойство с именем DefaultStatus. Оно позволяет любому клиенту, использующему этот тип столбца, задать, какое из трех значений Statuslmage Будет отображаться по умолчанию, если никакого значения явным образом не задано, ни через привязку данных, ни посредством программной установки значения ячейки. Установщик для этого свойства модифицирует поле, которое отслеживает текущее значение по умолчанию. К свойству DefaultStatus Обращается метод StatusCell. GetFormattedValue, Описанный выше.

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

b это означает что он

На форму был также добавлен элемент управления ListView, А его свойство Dock Установлено равным Fill. Это означает, что он будет заполнять остаток центральной части формы. В данном случае, поскольку здесь нет других элементов управления, состыкованных сверху, снизу или справа, он заполнит всю оставшуюся часть формы. С левой стороны он будет достигать границы элемента управления дерева, который был состыкован слева. Если бы на форме были другие состыкованные элементы управления, они прикрепились бы к соответствующим границам и затем попытались расшириться вплоть до смежных границ. Если вы спланируете свою форму таким образом, размер ее двух частей нельзя будет изменять, поэтому для такого рода планировки вы обычно будете применять SplitContainer . Тогда и Treeview, И ListView Станут дочерними элементами контейнеров в SplitContainer И могут быть состыкованы по центру , Заполняя отведенные им части формы по обе стороны разделителя. Когда вы выбираете на форме элемент управления и выбираете в окне Properties свойство Dock, Открывается графический редактор свойства, показанный на рис. В. 17.

Важное значение имеет порядок, в котором вы помещаете элементы управления на форму и устанавливаете их свойства Dock. Если в тот момент, когда элемент управления пытается расшириться до сторон, примыкающих к той, с которой он состыкован, на его пути оказывается другой, уже состыкованный, элемент управления, то он расширится только до кромки этого другого элемента управления. Поэтому, если вы помещаете на форму один элемент управления и устанавливаете его свойство Dock Равным Тор, А затем помещаете на форму другой элемент управления, также устанавливая его свойство Dock Равным Тор, То второй элемент управления будет состыкован с низом первого, а первый элемент управления — с верхом формы. Действуя подобным образом, вы можете создавать при помощи стыковки довольно сложные планировки. Однако поместить все элементы управления на форму в правильном порядке и нужным образом установить их свойства Dock Может оказаться непростым делом.