Исследование MS Visual С#, страница 24

{

string s = "Current cell: " + grid.CurrentCell.RowNumber + ", "

     + grid.CurrentCell.ColumnNumber;       // Готовим строку сообщения

foreach (Man m in menList)   // Добавляем в нее весь список имен

  s += "\n  Name: " + m.Name;

MessageBox.Show(s, "Current cell and menList data");

}

Каждый раз, когда пользователь переводит фокус из одной ячейки в другую, управление передается в функцию обработки события. Суть опыта в том, чтобы сделать видимыми изменения, происходящие при этом в коллекции menList. Сравните поведение компонента при стирании поля, управляемого свойством Age с тем, которое обнаруживается при стирании поля, управляемого свойством Name, объясните различие и удалите обработчик события CurrentCellChanged, так как он будет мешать в следующем опыте.

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

Покажем, что перемещение по ячейкам таблицы можно осуществлять не только с помощью мыши и клавиш управления курсором, но и с помощью специального элемента управления, называемого CurrencyManager. Для управления объектами класса CurrencyManager оконная форма может пользоваться объектом специального класса BindingContext. В настоящий момент источником данных таблицы является объект класса ArrayList. Он не имеет свойства Current, то есть не умеет отслеживать свою текущую позицию. Чтобы добиться этого, надо связать три сущности: (элемент типа CurrencyManager, компонент DataGrid и элемент типа ArrayList.

В пространстве имен System.Windows.Forms определен класс BindingManagerBase. Он является абстрактным, но имеет два производных класса: CurrencyManager и PropertyManager, которые позволяют синхронизировать позиции и состояния отдельных элементов управления на оконной форме, привязанных к одному и тому же источнику данных. Для иллюстрации возможностей класса CurrencyManager:

1.  Вставьте в форму список изображений ImageList и заполните его четырьмя изображениями,

2.  Вставьте в форму панель инструментов и добавьте в нее четыре кнопки управления текущей позицией таблицы grid, которая будет синхронизирована с текущей позицией списка menList.

3.  Свяжите изображения с кнопками панели инструментов так, как мы делали это в предыдущем проекте.

4.  Для отображения текущего элемента списка введите в форму элемент типа Label и установите его свойства: (Name) — lblName, Text — lblName, Autosize — True. После этих преобразований оконная форма должна приобрести вид, показанный на рисунке.

В классе Form1 должны появиться строки с объявлениями новых элементов, которые вставил дизайнер формы. Я предполагаю, что идентификаторы элементов (свойство Name) были заданы так, как показано.

private System.Windows.Forms.Button bNext;

private System.Windows.Forms.Button bPrev;

private System.Windows.Forms.Button bFirst;

private System.Windows.Forms.Button bLast;

private System.Windows.Forms.Label lblName;

Теперь вручную добавьте в класс формы объявление элемента типа CurrencyManager — синхронизатора текущей позиции.

private CurrencyManager cm = null; // Синхронизатор позиций

Измените конструктор класса так, чтобы он произвел увязку трех объектов (grid, menList и cm).

public Form1()

{

InitializeComponent();

MakeList();

grid.DataSource = menList; // Связывание коллекции с компонентом DataGrid

  cm = (CurrencyManager)grid.BindingContext[menList];     // Получаем ссылку на синхронизатор

lblName.Text = ((Man)cm.Current).Name;

}

Последнее присвоение синхронизирует текст метки с текущим значением списка. В момент появления окна текст будет отображать имя первого объекта в списке menList. Для того, чтобы ожили четыре кнопки управления перемещением по строкам таблицы DataGrid, перейдите в режим дизайна и дважды щелкните по панели инструментов. В классе появятся функция обработки события по умолчанию. Введите в нее код, который отслеживает текущую позицию и синхронизирует текст метки lblName.

private void toolBar1_ButtonClick (object s, ToolBarButtonClickEventArgs e)

{

  //==== Свойство Position синхронизатора смещает текущую позицию — Current

if (e.Button == bFirst)       // Реакция на нажатие кнопки bFirst

  cm.Position = 0;

else if (e.Button == bNext)

  cm.Position++;

else if (e.Button == bPrev)

  cm.Position--;

else if (e.Button == bLast)

  cm.Position = menList.Count - 1;

lblName.Text = ((Man)cm.Current).Name;// Синнхронизация текста метки

}

Запустите и убедитесь, что таблица управляется с помощью кнопок и правильно отслеживается позиция. Это подтверждается текстом в поле lblName. Для того, чтобы сделать это поле более информативным, введите в класс Man метод ToString, забытый нами при переносе кода класса из ранней версии.

public override string ToString()// Переопределение виртуальной функции, наследованной от класса Object

{

return name.PadRight(15) + " Age: " + age;

}

Теперь замените в методе toolBar1_ButtonClick класса Form1 строку:

lblName.Text = ((Man)cm.Current).Name;

на

lblName.Text = ((Man)cm.Current).ToString();

Дальнейший ход развития функциональности очевиден. Вы должны добавить кнопки управления, которые задействуют файловые операции. Добавьте кнопку поиска, который надо сначала произвести в списке menList, а затем синхронизировать grid с помощью cm. Для этого достаточно установить его свойство Position в то значение, которое соответствует найденному элементу. Это действие приведет в соответствие текущую позицию Current. Заметьте, что свойство Current элемента CurrencyManager доступно только для чтения, поэтому его нельзя изменить явным, или программным способом.