Чтение онлайн

ЖАНРЫ

Программирование для карманных компьютеров

Волков Владимир

Шрифт:

18. Теперь можно создать процедуру обработчика события загрузки формы, код которой приведен в листинге 6.7. Листинг 6.7

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)

Handles MyBase.Load

\'Если файл с данными отсутствует в текущем каталоге, мы его создаем, для

\'этого сначала получаем полный путь каталога, в котором расположена

\'программа, в строковую переменную dirStr

dirStr = IO.Path.GetDirectoryName_

(Reflection.Assembly.GetExecutingAssembly.GetName.CodeBase.ToString)

\'Проверяем, есть ли файл c заданным именем по полученному пути

If Not System.IO.File.Exists(dirStr + «\2005.xml») Then

\'Если файла нет – создаем его

\'Создаем экземпляр XmlDocument

Dim myxmlDoc As New Xml.XmlDocument

\'Создаем корневой тег и добавляем его к документу

Dim oROOT As Xml.XmlElement = myxmlDoc.CreateElement(«Y2005»)

myxmlDoc.AppendChild(oROOT)

\'Получаем текущую дату в переменную myDate

Dim myDate As Date = Date.Now

myDate = DateAdd(DateInterval.Day, – 1, myDate)

\'Заполняем файл тегами Data от сегодняшнего дня до конца текущего года

While Not myDate.ToShortDateString = «31.12.2005»

myDate = DateAdd(DateInterval.Day, 1, myDate)

Dim oData As Xml.XmlElement = myxmlDoc.CreateElement(«Data»)

oROOT.AppendChild(oData)

Dim oValue As Xml.XmlAttribute = _ myxmlDoc.CreateAttribute(«value»)

Dim oIndex As Xml.XmlAttribute = _ myxmlDoc.CreateAttribute(«Cnt»)

oValue.InnerText = myDate.ToShortDateString

oIndex.InnerText = «-1»

oData.SetAttributeNode(oValue)

oData.SetAttributeNode(oIndex)

End While

\'Создаем

заголовочную часть XML файла

Dim myPI As Xml.XmlProcessingInstruction = _

myxmlDoc.CreateProcessingInstruction_

(«xml», "version= 1.0 encoding=\'windows-1251 ")

myxmlDoc.InsertBefore(myPI, myxmlDoc.ChildNodes(0))

\'Сохраняем созданный документ

myxmlDoc.Save(dirStr + «\2005.xml»)

End If

\'Если файл со списком категорий отсутствует в текущем каталоге, мы его

\'создаем с пятью категориями Work1, Work2, Work3, Misc, Trash

If Not System.IO.File.Exists(dirStr + «\Category.xml») Then

If Not System.IO.File.Exists(dirStr + «\Category.xml») Then

Dim myxmlDoc As New Xml.XmlDocument

Dim oROOT As Xml.XmlElement = myxmlDoc.CreateElement(«Categoty»)

myxmlDoc.AppendChild(oROOT)

Dim oWork1 As Xml.XmlElement = myxmlDoc.CreateElement(«Work1»)

oROOT.AppendChild(oWork1)

Dim oWork2 As Xml.XmlElement = myxmlDoc.CreateElement(«Work2»)

oROOT.AppendChild(oWork2)

Dim oWork3 As Xml.XmlElement = myxmlDoc.CreateElement(«Work3»)

oROOT.AppendChild(oWork3)

Dim oMisc As Xml.XmlElement = myxmlDoc.CreateElement(«Misc»)

oROOT.AppendChild(oMisc)

Dim oTrash As Xml.XmlElement = myxmlDoc.CreateElement(«Trash»)

oROOT.AppendChild(oTrash)

Dim myPI As Xml.XmlProcessingInstruction = _

myxmlDoc.CreateProcessingInstruction_

(«xml», "version= 1.0 encoding=\'windows-1251 ")

myxmlDoc.InsertBefore(myPI, myxmlDoc.ChildNodes(0))

myxmlDoc.Save(dirStr + «\Category.xml»)

End If

D = DateTime.Now

Label1.Text = System.DateTime.Today.ToShortDateString

\'Вызываем процедуру загрузки данных в ListView

Data_Load(System.DateTime.Today.ToShortDateString)

End Sub

Чтобы создать и сохранить новый XML-документ, мы воспользовались классом XMLDocument, который позволяет представить существующий XML-документ в виде объекта с набором полей и методов для манипуляции этими полями. Он позволяет создавать и удалять элементы XML как по имени, так и по индексу, осуществлять поиск нужного элемента, заменять или дублировать элементы, сохранять измененный документ. Единственным недостатком этого класса является то, что документ полностью загружается в создаваемый объект. Поскольку на Pocket PC и файловая система, и оперативная память программы физически являются одним и тем же устройством, то просто происходит дублирование информации на время работы с документом.

19. Процедура загрузки данных для текущего дня в компонент ListView приведена в листинге 6.8.

Листинг 6.8

Private Sub Data_Load(ByVal MyDate As String)

\'Открываем файл, для это сначала получаем полный путь каталога,

\'в котором расположена программа в строковую переменную dirStr

dirStr = IO.Path.GetDirectoryName_

(Reflection.Assembly.GetExecutingAssembly.GetName.CodeBase.ToString)

\'Создаем экземпляр объекта XmlTextReader

Dim xmlrdrMy As New Xml.XmlTextReader(dirStr + «\2005.xml»)

Dim MyCount, MyIndex As Integer

Dim lvItem As ListViewItem

\'Не реагируем на пробелы и управляющие символы

xmlrdrMy.WhitespaceHandling = xmlrdrMy.WhitespaceHandling.None

\'Переходим к содержимому, пропуская заголовочную часть

xmlrdrMy.MoveToContent

\'В цикле считываем значения из файла, добавляем новую строку в ListView

\'для каждого тега Index и копируем значения атрибутов тега Index в

\'соответствующие поля записи ListView

ListView1.Items.Clear

ListView1.Refresh

While Not xmlrdrMy.EOF

If xmlrdrMy.Name = «Data» Then

If xmlrdrMy.GetAttribute(«value») = MyDate Then

MyIndex = CInt(xmlrdrMy.GetAttribute(«Cnt»))

For MyCount = 0 To MyIndex – 1

xmlrdrMy.Read

lvItem = New ListViewItem(xmlrdrMy.GetAttribute(«Category»))

ListView1.Items.Add(lvItem)

ListView1.Items.Item(MyCount). SubItems.Add_

(xmlrdrMy.GetAttribute(«StartOf»))

ListView1.Items.Item(MyCount). SubItems.Add(xmlrdrMy.GetAttribute(«EndOf»))

ListView1.Items.Item(MyCount). SubItems.Add(xmlrdrMy.GetAttribute(«Note»))

Next

End If

End If

\'Считываем следующий элемент из файла XML

xmlrdrMy.Read

End While

\'Закрываем файл

xmlrdrMy.Close

End Sub

В этом случае мы воспользовались классом XmlTextReader для считывания информации из файла. Класс XmlTextReader также позволяет разбирать содержимое XML-документа, но он не создает копию файла в памяти, а считывает его в один проход элемент за элементом. Переход к следующему элементу осуществляется вызовом метода Read.

20. Теперь нужно создать процедуру сохранения данных текущего дня в файл. Эта процедура должна запускаться при переходе от одной даты к другой, а также в момент закрытия приложения. Ее код приведен в листинге 6.9.

Листинг 6.9

Private Sub Data_Save(ByVal MyDate As String)

Dim MyCount, MyIndex As Integer

\'Создаем объект XmlDocument

Dim myxml As New Xml.XmlDocument

dirStr = IO.Path.GetDirectoryName_

(Reflection.Assembly.GetExecutingAssembly.GetName.CodeBase.ToString)

\'Загружаем файл в объект XmlDocument

myxml.Load(dirStr + «\2005.xml»)

\'Перебираем все узлы уровня Data и находим сохраняемую дату

For MyCount = 0 To myxml.ChildNodes(1). ChildNodes.Count – 1

If myxml.ChildNodes(1). ChildNodes(MyCount). Attributes(0). InnerText = MyDate Then

\'Удаляем все содержимое этого узла

myxml.ChildNodes(1). ChildNodes(MyCount). RemoveAll

\'И заполняем его текущим содержимым полей ListView. При этом мы создаем

\'заново атрибуты узла Data и узлы Index со всеми атрибутами для каждой

\'строки ListView

\'Создаем атрибут value для текущего узла Data

Dim myValue As Xml.XmlAttribute = myxml.CreateAttribute(«value»)

\'Присваиваем атрибуту value значение текущей даты

myValue.InnerText = MyDate

\'Добавляем атрибут value к текущему узлу Data

myxml.ChildNodes(1). ChildNodes(MyCount). Attributes.Append(myValue)

\'Проделываем предыдущие операции с атрибутом Cnt

Dim mIndex As Xml.XmlAttribute = myxml.CreateAttribute(«Cnt»)

mIndex.InnerText = ListView1.Items.Count

myxml.ChildNodes(1). ChildNodes(MyCount). Attributes.Append(mIndex)

\'Заполняем узел Data вложенными элементами Index

For MyIndex = 0 To ListView1.Items.Count – 1

Dim oIndex As Xml.XmlElement = myxml.CreateElement(«index»)

myxml.ChildNodes(1). ChildNodes(MyCount). AppendChild(oIndex)

Dim oCategory As Xml.XmlAttribute = myxml.CreateAttribute(«Category»)

oCategory.InnerText = ListView1.Items(MyIndex). SubItems(0). Text

myxml.ChildNodes(1). ChildNodes(MyCount). ChildNodes_

(MyIndex). Attributes.Append(oCategory)

Dim oStartOf As Xml.XmlAttribute = myxml.CreateAttribute(«StartOf»)

oStartOf.InnerText = ListView1.Items(MyIndex). SubItems(1). Text

myxml.ChildNodes(1). ChildNodes(MyCount). ChildNodes_

(MyIndex). Attributes.Append(oStartOf)

Dim oEndOf As Xml.XmlAttribute = myxml.CreateAttribute(«EndOf»)

oEndOf.InnerText = ListView1.Items(MyIndex). SubItems(2). Text

myxml.ChildNodes(1). ChildNodes(MyCount). ChildNodes_

(MyIndex). Attributes.Append(oEndOf)

Dim oNote As Xml.XmlAttribute = myxml.CreateAttribute(«Note»)

oNote.InnerText = ListView1.Items(MyIndex). SubItems(3). Text

myxml.ChildNodes(1). ChildNodes(MyCount). ChildNodes_

(MyIndex). Attributes.Append(oNote)

Next

\'Если найден и заполнен требуемый узел Data, прекращаем перебор узлов

Exit For

End If

Next

\'Сохраняем документ в файл

myxml.Save(dirStr + «\2005.xml»)

End Sub

21. Остальные процедуры будут не столь объемны. После того как файл был загружен и его содержимое было отображено в элементе ListView, надо написать обработчики событий для щелчков на компонентах PictureBox, которые играют роль кнопок. Поскольку при написании этих обработчиков понадобятся переменные, через которые данные будут передаваться из формы в форму, нужно создать модуль и объявить в нем эти переменные.

22. Выполнить команду Project ? Add Module. На экран будет выведено соответствующее

диалоговое окно. В строке Name нужно вместо предлагаемого имени указать имя Data, после чего нужно нажать кнопку Open. В окне редактора кода будет открыт пустой модуль. В нем нужно указать код, приведенный в листинге 6.10.

Листинг 6.10

Module Data

Public categorySt, startOfSt, endOfSt, noteSt As String

End Module

23. Процедура сохранения информации текущего дня при закрытии приложения описана в листинге 6.11. Листинг 6.11

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As

System.ComponentModel.CancelEventArgs) Handles MyBase.Closing

Data_Save(Label1.Text)

End Sub

24. Обработчик щелчка на кнопке PictureBox1, который осуществляет переход к предыдущему дню, приведен в листинге 6.12. Листинг 6.12

Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles PictureBox1.Click

Data_Save(Label1.Text)

D = DateAdd(DateInterval.Day, – 1, D)

Label1.Text = D.ToShortDateString

Data_Load(D.ToShortDateString)

End Sub

25. Обработчик щелчка на кнопке PictureBox2, который осуществляет переход к следующему дню, приведен в листинге 6.13. Листинг 6.13

Private Sub PictureBox2_Click(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles PictureBox2.Click

Data_Save(Label1.Text)

D = DateAdd(DateInterval.Day, 1, D)

Label1.Text = D.ToShortDateString

Data_Load(D.ToShortDateString)

End Sub

26. Обработчик щелчка на кнопке PictureBox3, который отвечает за добавление очередной записи в текущий день, показан в листинге 6.14. Листинг 6.14

Private Sub PictureBox3_Click(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles PictureBox3.Click

Dim lvIt As ListViewItem

\'Создаем диалоговую форму редактирования

Dim MyForm As New Form2

\'Устанавливаем флаг, показывающий, что был щелчок на кнопке 3

MyForm.Send = 3

\'Если ListView не пустой, копируем значения полей текущей записи в

\'переменные так, что время конца в текущей записи станет временем начала

\'в создаваемой записи

If ListView1.Items.Count > 0 Then

categorySt = ListView1.Items.Item_

(ListView1.Items.Count – 1). SubItems(0). Text

startOfSt = ListView1.Items.Item_

(ListView1.Items.Count – 1). SubItems(2). Text

endOfSt = startOfSt

noteSt = ""

Else

categorySt = ""

startOfSt = ""

endOfSt = ""

noteSt = ""

End If

\'Выводим на экран форму редактирования записи

If MyForm.ShowDialog = DialogResult.OK Then

\'И если редактирование завершилось щелчком на кнопке OK, добавляем новую

\'запись в ListView

lvIt = New ListViewItem(categorySt)

ListView1.Items.Add(lvIt)

ListView1.Items.Item.(ListView1.Items.Count – 1). SubItems.Add(startOfSt)

ListView1.Items.Item.(ListView1.Items.Count – 1). SubItems.Add(endOfSt)

ListView1.Items.Item.(ListView1.Items.Count – 1). SubItems.Add(noteSt)

End If

End Sub

27. Обработчик щелчка на кнопке PictureBox4, который отвечает за редактирование текущей записи, показан в листинге 6.15. Листинг 6.15

Private Sub PictureBox4_Click(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles PictureBox4.Click

\'Если в ListView есть выделенная строка, тогда редактируем

If ListView1.SelectedIndices.Count > 0 Then

Dim MyForm As New Form2

\'Сообщаем форме редактирования, что был щелчок на кнопке 4

MyForm.Send = 4

\'Копируем значения полей записи в переменные

categorySt = ListView1.Items(ListView1.SelectedIndices_(0)). SubItems(0). Text

startOfSt = ListView1.Items(ListView1.SelectedIndices(0)). SubItems(1). Text

endOfSt = ListView1.Items(ListView1.SelectedIndices(0)). SubItems(2). Text

noteSt = ListView1.Items(ListView1.SelectedIndices(0)). SubItems(3). Text

\'Если редактирование завершилось щелчком на кнопке OK, копируем возвращенные

\'значения переменных в соответствующие поля ListView

If MyForm.ShowDialog = DialogResult.OK Then

ListView1.Items(ListView1.SelectedIndices(0)). SubItems(0). Text = categorySt

ListView1.Items(ListView1.SelectedIndices(0)). SubItems(1). Text = startOfSt

ListView1.Items(ListView1.SelectedIndices(0)). SubItems(2). Text = endOfSt

ListView1.Items(ListView1.SelectedIndices(0)). SubItems(3). Text = noteSt

End If

End If

End Sub

28. Код обработчика щелчка на кнопке PictureBox5 (удаление текущей записи) приведен в листинге 6.16. Листинг 6.16

Private Sub PictureBox5_Click(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles PictureBox5.Click

If ListView1.SelectedIndices.Count > 0 Then

ListView1.Items.Remove(ListView1.Items(ListView1.SelectedIndices(0)))

End If

End Sub

29. После того как были написаны обработчики для элементов управления основной формы, нужно сделать то же самое для формы редактирования данных. Сначала нужно объявить в этой форме переменную Send, как показано в листинге 6.17. Лиситнг 6.17

Public Class Form2

Public Send As Integer

30. Теперь можно написать основные обработчики событий компонентов. Обработчик события загрузки формы должен различать, щелчком на котором элементе была загружена форма, и вести себя соответственно. Это поведение задается в коде, который приведен в листинге 6.18. Листинг 6.18

Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)

Handles MyBase.Load

Dim myCount As Integer

Dim myStrTime As String

ComboBox2.Items.Clear

ComboBox3.Items.Clear

\'Загружаем содержимое двух компонентов выпадающих списков, которые

\'должны отображать выбор временных интервалов от 00.00 до 23.55 c

\'дискретностью в 5 минут

For myCount = 0 To 287

Dim myTime1 As TimeSpan = TimeSpan.FromMinutes(myCount * 5)

myStrTime = myTime1.ToString

myStrTime = myStrTime.Substring(0, 5)

ComboBox2.Items.Add(myStrTime)

ComboBox3.Items.Add(myStrTime)

Next

\'Читаем список категорий в ComboBox1

Dim myxmlDoc As New Xml.XmlDocument

Dim dirStr As String

dirStr = IO.Path.GetDirectoryName_

(Reflection.Assembly.GetExecutingAssembly.GetName.CodeBase.ToString)

ComboBox1.Items.Clear

myxmlDoc.Load(dirStr + «\Category.xml»)

For myCount = 0 To myxmlDoc.ChildNodes.Item(1). ChildNodes.Count – 1

ComboBox1.Items.Add_ (myxmlDoc.ChildNodes.Item(1). ChildNodes.Item(myCount). Name)

Next

ComboBox1.SelectedIndex = 0

ComboBox2.SelectedIndex = 0

ComboBox3.SelectedIndex = 0

\'Устанавливаем в ComboBox1 категорию, которая задана в последней

\'строке ListView

For myCount = 0 To ComboBox1.Items.Count – 1

If ComboBox1.Items(myCount) = categorySt Then

ComboBox1.SelectedIndex = myCount

Exit For

End If

Next

\'Для второго и третьего ComboBox так же устанавливаем значения

For myCount = 0 To ComboBox2.Items.Count – 1

If ComboBox2.Items(myCount) = startOfSt Then

ComboBox2.SelectedIndex = myCount

Exit For

End If

Next

For myCount = 0 To ComboBox3.Items.Count – 1

If ComboBox3.Items(myCount) = endOfSt Then

ComboBox3.SelectedIndex = myCount

Exit For

End If

Next

TextBox1.Text = noteSt

End Sub

31. Обработчик щелчка на кнопке OK формы редактирования показан в листинге 6.19. Листинг 6.19

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

Handles Button1.Click

\'Возвращаем в переменные установленные в элементах управления значения

categorySt = Me.ComboBox1.Text

startOfSt = Me.ComboBox2.Text

endOfSt = Me.ComboBox3.Text

noteSt = Me.TextBox1.Text

\'Возвращаем результат работы диалогового окна

DialogResult = DialogResult.OK

\'Закрываем форму

Me.Close

End Sub

32. Код обработчика щелчка на кнопке Cancel формы редактирования приведен в листинге 6.20. Листинг 6.20

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

Handles Button2.Click

DialogResult = DialogResult.Cancel

Me.Close

End Sub

33. Осталось задать код еще двух обработчиков, предназначенных для автоматического отображения и скрытия программной панели ввода (виртуальной клавиатуры) при приобретении и потери фокуса текстовым полем TextBox. Код этих обработчиков приведен в листинге 6.21. Листинг 6.21

Private Sub TextBox1_GotFocus(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles TextBox1.GotFocus

InputPanel1.Enabled = True

End Sub

Private Sub TextBox1_LostFocus(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles TextBox1.LostFocus

InputPanel1.Enabled = False

End Sub

Поделиться с друзьями: