Текст книги "Программирование мобильных устройств на платформе .NET Compact Framework"
Автор книги: Иво Салмре
Жанр:
Программирование
сообщить о нарушении
Текущая страница: 67 (всего у книги 69 страниц)
'–
Dim trasparencyInfo As System.Drawing.Imaging.ImageAttributes
trasparencyInfo = New System.Drawing.Imaging.ImageAttributes
'–
'Задать прозрачный цвет
'–
trasparencyInfo.SetColorKey(System.Drawing.Color.Yellow, _
System.Drawing.Color.Yellow)
'Задать прямоугольник рисунка
Dim rect As System.Drawing.Rectangle = _
New System.Drawing.Rectangle(0, 0, _
m_backgroundBitmap.Width, m_backgroundBitmap.Height)
'–
'Нарисовать изображение ПЕРЕДНЕГО ПЛАНА поверх изображения ЗАДНЕГО ПЛАНА
'и использовать прозрачный цвет в ImageAttributes для создания окна
'прозрачности, через которое виден задний план
'–
gfx.DrawImage(m_foregroundBitmap, rect, 0, 0, _
m_foregroundBitmap.Width, m_foregroundBitmap.Height, _
System.Drawing.GraphicsUnit.Pixel, trasparencyInfo)
'Очистить
gfx.Dispose()
'Показать результат в виде растрового изображения
PictureBox1.Image = m_backgroundBitmap
End Sub
Листинг 13.6. Код формы, демонстрирующий загрузку встроенных ресурсов
'–
'Загрузить изображение и отобразить его в объекте PictureBox
'–
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
LoadImageFromResource()
PictureBox1.Image = m_myBitmapImage
End Sub
Private m_myBitmapImage As System.Drawing.Bitmap
'–
'Загрузить изображение, которое хранится в виде встроенного ресурса
'в нашей сборке
'–
Public Sub LoadImageFromResource()
'Если изображение уже загружено,
'то не имеет смысла делать это повторно.
If Not (m_myBitmapImage Is Nothing) Then
Return
End If
'–
'Получить ссылку на двоичную сборку нашего приложения
'–
Dim thisAssembly As System.Reflection.Assembly = _
System.Reflection.Assembly.GetExecutingAssembly()
'–
'Получить имя сборки
'–
Dim thisAssemblyName As System.Reflection.AssemblyName = _
thisAssembly.GetName()
Dim assemblyName As String = thisAssemblyName.Name
'–
'Извлечь поток изображения из нашей сборки и создать соответствующую ему
'битовую карту в памяти
'ПРИМЕЧАНИЕ: Имя потока ресурса ResourceStream ЧУВСТВИТЕЛЬНО К РЕГИСТРУ,
' поэтому имя изображения должно В ТОЧНОСТИ совпадать с именем
' файла изображения, который вы добавили в проект
'–
m_myBitmapImage = New System.Drawing.Bitmap( _
thisAssembly.GetManifestResourceStream( _
assemblyName + ".MyImage.PNG"))
End Sub
Примеры к главе 14 (данные)
Листинг 14.1. Простой пример создания и использования объекта ADO.NET DataSet
'Объект DataSet, который мы собираемся загрузить
Private m_myDataSet As System.Data.DataSet
'Константы, которые будут использоваться
Const FILE_EMPTY_DATASET As String = "EmptyDataSet.xml"
Const FILE_1TABLE_DATASET As String = "1TableDataSet.xml"
Const dividerLine As String = _
"–" + vbCrLf
'–
'Загрузить содержимое файла и присоединить его к тексту,
'содержащемуся в элементе управления textBox1
'–
Private Sub addFileContentsToTextBox(ByVal fileName As String)
'Открыть файл и считать его содержимое
Dim myStreamReader As System.IO.StreamReader
myStreamReader = System.IO.File.OpenText(fileName)
Dim fileText As String = myStreamReader.ReadToEnd()
'Закрыть файл
myStreamReader.Close()
'Присоединить содержимое к тексту, находящемуся в текстовом окне
TextBox1.Text = TextBox1.Text + _
dividerLine + "FILE: '" + fileName + "'" + vbCrLf + _
dividerLine + fileText + vbCrLf
End Sub
'–
'1. Создает набор данных,
' сохраняет набор данных в виде XML,
' отображает результаты в текстовом окне
'2. Добавляет таблицу данных в набор данных,
' добавляет два типизированных столбца в таблицу данных,
' добавляет две строки в таблицу данных,
' сохраняет набор данных в виде XML,
' отображает результаты в текстовом окне
'–
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'Очистить текстовое окно от содержимого
TextBox1.Text = ""
'===========================================
'1. Создать новый набор данных
'===========================================
m_myDataSet = New System.Data.DataSet("HelloWorld-DataSet")
'Записать содержимое ADO.NET DataSet в виде XML и отобразить
'файл в текстовом окне
m_myDataSet.WriteXml(FILE_EMPTY_DATASET)
addFileContentsToTextBox(FILE_EMPTY_DATASET)
'==================================================
'2. Добавить таблицу данных в набор данных ADO.NET,
' а также 2 строки данных в таблицу данных
'==================================================
Dim myTestTable As System.Data.DataTable
myTestTable = m_myDataSet.Tables.Add("TestTable")
'–
'Добавить 2 столбца в таблицу
'–
'Добавить столбец данных в таблицу DataTable набора DataSet
myTestTable.Columns.Add("TestColumn0", _
GetType(System.DateTime))
'Добавить строковый столбец в таблицу DataTable набора DataSet
myTestTable.Columns.Add("TestColumn1", GetType(String))
'–
'Добавить строки данных в таблицу
'–
'Добавить строку данных в таблицу данных
Dim rowOfData() As Object
ReDim rowOfData(1)
'Столбец 0 – это тип данных
rowOfData(0) = System.DateTime.Today
'Столбец 1 – это строковый тип
rowOfData(1) = "а string of data today"
myTestTable.Rows.Add(rowOfData)
'Добавить вторую строку данных в таблицу данных
Dim rowOfData2() As Object
ReDim rowOfData2(1) 'Столбец 0 – это тип данных
rowOfData2(0) = System.DateTime.Today.AddDays(1)
'Столбец 1 – это строковый тип
rowOfData2(1) = "tomorrow's string"
myTestTable.Rows.Add(rowOfData2)
'Записать содержимое набора ADO.NET DataSet в виде XML и отобразить
'файл в текстовом окне
m_myDataSet.WriteXml(FILE_1TABLE_ DATASET)
addFileContentsToTextBox(FILE_1TABLE_DATASET)
End Sub
Листинг 14.2. Использование параметра XMLWriteMode при сохранении объекта ADO.NET DataSet
'–
'Необходимость в этой функции возникает по той причине, что .NET Compact
'Framework не поддерживает перегрузку:
' "public voidWriteXml(string, XmlWriteMode);"
'
'в качестве функции-члена "public" (только "private")
'–
Sub writeDataSetToFile(ByVal ds As System.Data.DataSet, _
ByVal filename As String, _
ByVal xmlWriteMode As System.Data.XmlWriteMode)
'Создать объект XmlWriter для записи наших XML-данных
Dim xmlWriter As System.Xml.XmlWriter
xmlWriter = New System.Xml.XmlTextWriter(filename, _
System.Text.Encoding.Default)
'ПРИМЕЧАНИЕ: Эта перегруженная версия не является общедоступной (public)!
'ds.WriteXml(filename, xmlWriteMode)
'Вместо этого используем следующую функцию:
ds.WriteXml(xmlWiiter, xmlWriteMode)
xmlWriter.Close() 'Важно закрыть файл!
End Sub
Листинг 14.3. Сравнение производительности различных вариантов доступа к данным с использованием объектов DataSet
Private m_myDataSet As System.Data.DataSet 'Набор данных для тестирования
'Индексы столбцов и таблицы, подлежащие кэшированию
Private m_indexesLookedUp As Boolean = False
Private Const INVALID_INDEX As Integer = -1
Private m_IndexOfTestColumn_CreditCard _
As Integer = INVALID_INDEX
Private m_IndexOfTestColumn_TravelDate _
As Integer = INVALID_INDEX
Private m_IndexOfTestTable As Integer = INVALID_INDEX
'Столбцы данных и таблица, подлежащих кэшированию
Private m_TestColumn_CreditCard As System.Data.DataColumn
Private m_TestColumn_TravelDate As System.Data.DataColumn
Private m_TableCustomerInfo As System.Data.DataTable
Public Enum testType '3 вида тестов, которые мы можем выполнять
textColumnLookup
cachedIndexLookup
cachedColumnObject
End Enum
'Эти константы определяют размерные характеристики тестов
Const DUMMY_ROWS_OF_DATA As Integer = 100
Const NUMBER_TEST_ITERATIONS As Integer = 500
'Табличная информация
Const TABLE_NAME_PASSENGERINFO As String = "CustomerTravelInfo"
Const COLUMN_NAME_DATE_OF_TRAVEL As String = "DateOfTravel"
Const COLUMN_NAME_PASSENGER_NAME As String = "PassengerName"
Const COLUMN_NAME_PASSENGER_CREDIT_CARD As String = _
"PassengerCreditCard"
Const TEST_CREDIT_CARD As String = "IvoCard-987-654-321-000"
'–
'Создает набор данных
'–
Private Sub createDataSet()
'1. Создать новый объект DataSet
m_myDataSet = New System.Data.DataSet("TravelService Dataset")
'2. Добавить объект DataTable в объект ADO.NET DataSet
Dim myTestTable As System.Data.DataTable
myTestTable = m_myDataSet.Tables.Add(TABLE_NAME_PASSENGERINFO)
'Добавить 2 столбца в таблицу
'Добавить столбец данных в таблицу DataTable набора данных DataSet
myTestTable.Columns.Add(COLUMN_NAME_DATE_OF_TRAVEL, _
GetType(System.DateTime))
'Добавить столбец строк в таблицу DataTable набора данных DataSet
myTestTable.Columns.Add(COLUMN_NAME_PASSENGER_NAME, _
GetType(String))
'Добавить столбец строк в таблицу DataTable набора данных DataSet
myTestTable.Columns.Add(COLUMN_NAME_PASSENGER_CREDIT_CARD, _
GetType(String))
'Данные для размещения в строках данных
Dim objArray() As Object ReDim objArray(2)
'–
'Добавить строки данных в таблицу
'–
Dim buildTestString As System.Text.StringBuilder
buildTestString = New System.Text.StringBuilder
Dim addItemsCount As Integer
For addItemsCount = 1 To DUMMY_ROWS_OF_DATA
'Выбрать день отъезда пассажира
objArray(0) = System.DateTime.Today.AddDays(addItemsCount)
'Выбрать имя пассажира
buildTestString.Length = 0
buildTestString.Append("TestPersonName")
buildTestString.Append(addItemsCount)
objArray(1) = buildTestString.ToString()
'Связать с пассажиром текстовый номер кредитной карточки
buildTestString.Length = 0
buildTestString.Append("IvoCard-000-000-0000-")
buildTestString.Append(addItemsCount)
objArray(2) = buildTestString.ToString()
'Добавить элементы массива в строку набора данных
myTestTable.Rows.Add(objArray)
Next
'Добавить элемент, поиск которого мы хотим проводить при выполнении теста
objArray(0) = System.DateTime.Today
objArray(1) = "Ms. TestPerson"
objArray(2) = ТЕST_CREDIT_CARD
'Добавить элементы массива в строку набора данных
myTestTable.Rows.Add(objArray)
End Sub
'–
'Найти и кэшировать все индексы набора данных, которые нам нужны
'–
Private Sub cacheDataSetInfo()
'Выйти из функции, если индексы уже загружены
If (m_indexesLookedUp = True) Then Return
'Кэшировать индекс таблицы
m_IndexOfTestTable = _
m_myDataSet.Tables.IndexOf(TABLE_NAME_PASSENGERINFO)
'–
'Итерировать по всем столбцам нашей таблицы
'и кэшировать индексы нужных столбцов
'–
mTableCustomerInfo = m_myDataSet.Tables(m_IndexOfTestTable)
Dim dataColumnCount As Integer
dataColumnCount = m_TableCustomerInfo.Columns.Count
Dim myColumn As System.Data.DataColumn
Dim colIdx As Integer
While (colIdx < dataColumnCount)
myColumn = m_TableCustomerInfo.Columns(colIdx)
'Предпринимать поиск, только если это еще не сделано
If (m_IndexOfTestColumn_CreditCard = INVALID_INDEX) Then
'Проверить, совпадает ли имя
If (myColumn.ColumnName = _
COLUMN_NAME_PASSENGER_CREDIT_CARD) Then
'Кэшировать индекс
m_IndexOfTestColumn_CreditCard = colIdx
'Кэшировать столбец
m_TestColumn_CreditCard = myColumn
GoTo next_loop_iteration 'Опустить другие операции сравнения...
End If 'Endif: сравнение строк
End If
If (m _IndexOfTestColumn_TravelDate = INVALID_INDEX) Then
'Проверить, совпадает ли имя
If (myColumn.ColumnName = _
COLUMN_NAME_DATE_OF_TRAVEL) Then
'Кэшировать индекс
m_IndexOfTestColumn_TravelDate = colIdx
'Кэшировать столбец
m_TestColumn_TravelDate = myColumn
GoTo next_loop_iteration 'Опустить другие операции сравнения
End If 'Endif: сравнение строк
End If
next_loop_iteration:
colIdx = colIdx + 1
End While
m_indexesLookedUp = True
End Sub
'–
'Выполнить тест.
'–
Sub changeDayOfTravel_test(ByVal kindOfTest As testType)
'Отобразить курсор ожидания
System.Windows.Forms.Cursor.Current = _
System.Windows.Forms.Cursors.WaitCursor
'Начать с известной даты
Dim newDate As System.DateTime
newDate = System.DateTime.Today
changeDayOfTravel_textColumnLookup(TEST_CREDIT_CARD, newDate)
'ДОПУСТИМО ТОЛЬКО ДЛЯ ТЕСТОВОГО КОДА!!!
'Вызов сборщика мусора в коде ЗАМЕДЛИТ работу вашего приложения!
System.GC.Collect()
Const testNumber As Integer = 0
'Настроить соответствующим образом в зависимости от вида выполняемого теста
Select Case (kindOfTest)
Case testType.textColumnLookup
PerformanceSampling.StartSample(testNumber, _
"Text based Column lookup.")
Case testType.cachedIndexLookup
PerformanceSampling.StartSample(testNumber, _
"Cached Column Index lookup.")
Case testType.cachedColumnObject
PerformanceSampling.StartSample(testNumber, _
"Cached Column objects")
Case Else
Throw New Exception("Unknown state!")
End Select
'Выполнить тест!
Dim testCount As Integer
For testCount = 1 To NUMBER_TEST_ITERATIONS
'Передвинуть дату вперед на один день
newDate = newDate.AddDays(1)
Dim numberRecordsChanged As Integer = 0
'Какой вид теста мы выполняем?
Select Case (kindOfTest)
Case testType.textColumnLookup
'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Просмотреть все имена, используя СТРОКИ
numberRecordsChanged = _
changeDayOfTravel_textColumnLookup( _
TEST_CREDIT_CARD, newDate)
Case testType.cachedIndexLookup
'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированные индексы
numberRecordsChanged = _
changeDayOfTravel_cachedColumnIndex( _
TEST_CREDIT_CARD, newDate)
Case testType.cachedColumnObject
'НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированные объекты
numberRecordsChanged = _
changeDayOfTravel_CachedColumns( _
TEST_CREDIT_CARD, newDate)
End Select
'Убедиться в том, что тест выполняется, как и ожидалось
If (numberRecordsChanged <> 1) Then
MsgBox("No matching records found. Test aborted!")
Return
End If
Next
'Получить время, которое потребовалось для выполнения теста
PerformanceSampling.StopSample(testNumber)
'Обычный курсор
System.Windows.Forms.Cursor.Current = _
System.Windows.Forms.Cursors.Default
'Отобразить результаты выполнения теста
Dim runInfo As String = NUMBER_TEST_ITERATIONS.ToString() + _
"x" + DUMMY_ROWS_OF_DATA.ToString() + ": "
MsgBox(runInfo + _
PerformanceSampling.GetSampleDurationText(testNumber))
End Sub
'ФУНКЦИЯ ПОИСКА, ОБЛАДАЮЩАЯ НИЗКОЙ ПРОИЗВОДИТЕЛЬНОСТЬЮ
Private Function changeDayOfTravel_textColumnLookup( _
ByVal creditCardNumber As String, _
ByVal newTravelDate As System.DateTime) As Integer
Dim numberRecordsChanged As Integer
'Найти имя таблицы
Dim dataTable_Customers As System.Data.DataTable
'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск в таблице, используя
'сравнение строк!
dataTable_Customers = _
m_myDataSet.Tables(TABLE_NAME_PASSENGERINFO)
Dim currentCustomerRow As System.Data.DataRow
For Each currentCustomerRow In dataTable_Customers.Rows
Dim currentCreditCard As String
'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск в таблице, используя
'сравнение строк!
currentCreditCard = CType( _
currentCustomerRow(COLUMN_NAME_PASSENGER_CREDIT_CARD), String)
'Проверить, является ли данная кредитная карточка искомой
If (creditCardNumber = currentCreditCard) Then
'Изменить дату отъезда
'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск столбца, используя
'сравнение строк!
Dim currentTravelDate As System.DateTime = CType( _
currentCustomerRow(COLUMN_NAME_DATE_OF_TRAVEL), _
System.DateTime)
If (currentTravelDate <> newTravelDate) Then
'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск столбца, используя
'сравнение строк!
currentCustomerRow(COLUMN_NAME_DATE_OF_TRAVEL) = _
newTravelDate
numberRecordsChanged = numberRecordsChanged + 1
End If
End If 'endif: сравнение строк
Next 'end for each
Return numberRecordsChanged 'Количество обновленных записей
End Function
'ФУНКЦИЯ, ХАРАКТЕРИЗУЮЩАЯСЯ НЕСКОЛЬКО ЛУЧШЕЙ ПРОИЗВОДИТЕЛЬНОСТЬЮ
Private Function changeDayOfTravel_cachedColumnIndex( _
ByVal creditCardNumber As String, ByVal newTravelDate _
As DateTime) As Integer
Dim numberRecordsChanged As Integer
'Поиск имени таблицы
Dim dataTable_Customers As System.Data.DataTable
'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: использовать кэшированный индекс
dataTable_Customers = _
m_myDataSet.Tables(m_IndexOfTestTable)
Dim currentCustomerRow As System.Data.DataRow
For Each currentCustomerRow In dataTable_Customers.Rows
Dim currentCreditCard As String
'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: использовать кэшированный индекс столбца!
currentCreditCard = CType(currentCustomerRow( _
m_IndexOfTestColumn_CreditCard), String)
'Проверить, совпадает ли номер кредитной карточки
If (creditCardNumber = currentCreditCard) Then
'Изменить дату отъезда
'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
Dim currentTravelDate As System.DateTime = CType( _
currentCustomerRow (m_IndexOfTestColumn_TravelDate), System.DateTime)
If (currentTravelDate <> newTravelDate) Then
'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
currentCustomerRow(m_IndexOfTestColumn_TravelDate) = _
newTravelDate
numberRecordsChanged = numberRecordsChanged + 1
End If
End If
Next
Return numberRecordsChanged 'Количество обновленных записей
End Function
'ФУНКЦИЯ, ОБЛАДАЮЩАЯ НАИЛУЧШЕЙ ПРОИЗВОДИТЕЛЬНОСТЬЮ
Private Function changeDayOfTravel_CachedColumns( _
ByVal creditCardNumber As String, _
ByVal newTravelDate As System.DateTime) As Integer
Dim numberRecordsChanged As Integer
'Найти имя таблицы
Dim dataTable_Customers As System.Data.DataTable = _
m_TableCustomerInfo
Dim currentCustomerRow As System.Data.DataRow
For Each currentCustomerRow In dataTable_Customers.Rows
Dim currentCreditCard As String
'НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
currentCreditCard = CType( _
currentCustomerRow(m_TestColumn_CreditCard), _
String)
'Проверить, совпадает ли номер кредитной карточки
If (creditCardNumber = currentCreditCard) Then
'Изменить дату отъезда
'НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
Dim currentTravelDate As System.DateTime = CType( _
currentCustomerRow(m_TestColumn_TravelDate), _
System.DateTime)
If (currentTravelDate <> newTravelDate) Then
'НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
currentCustomerRow(m_TestColumn_TravelDate) = _
newTravelDate
numberRecordsChanged = numberRecordsChanged + 1
End If
End If
Next
Return numberRecordsChanged 'Количество обновленных записей
End Function
'Событие щелчка на кнопке
Private Sub buttonRunTest_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles buttonRunTest.Click
createDataSet()
cacheDataSetInfo()
'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать поиск по строкам
changeDayOfTravel_test(testType.textColumnLookup)
'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать поиск по целочисленным индексам
changeDayOfTravel_test(testType.cachedIndexLookup)
'НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать поиск по объектам столбцов
changeDayOfTravel_test(testType.cachedColumnObject)
End Sub
Листинг 14.4. Результаты тестирования производительности при использовании пользовательского формата данных вместо объектов DataSet
'Определение размерных характеристик теста
Const DUMMY _ROWS_OF_DATA As Integer = 100
Const NUMBER_TEST_ITERATIONS As Integer = 500
Const TABLE_NAME_PASSENGERINFO As String = "CustomerTravelInfo"
Const TEST_CREDIT_CARD As String = "IvoCard-987-654-321-000"
Private m_data_creditCards() As String
Private m_data_names() As String
Private m_data_travelDates() As System.DateTime
'–
'Создает массив данных (вместо использования объектов DataSet)
'–
Private Sub createDataSet()
'=============================================
'1. Создать пространство для размещения данных
'=============================================
ReDim m_data_creditCards(DUMMY_ROWS_OF_DATA)
ReDim m_data_names(DUMMY_ROWS_OF_DATA)
ReDim m_data_travelDates(DUMMY_ROWS_OF_DATA)
'–
'Добавить строки данных
'–
Dim buildTestString As System.Text.StringBuilder
buildTestString = New System.Text.StringBuilder
Dim addItemsCount As Integer
For addItemsCount = 0 To DUMMY_ROWS_OF_DATA
'Выбрать день отъезда пассажира
m_data_travelDates(addItemsCount) = _
System.DateTime.Today.AddDays(addItemsCount)
'–
'Выбрать имя пассажира
'–
'Очистить строку
buildTestString.Length = 0
buildTestString.Append("TestPersonName")
buildTestString.Append(addItemsCount)
m_data_names(addItemsCount) = buildTestString.ToString()
'–
'Связать с пассажиром текстовый номер кредитной карточки
'–
'Строка значения третьего столбца набора данных
buildTestString.Length = 0
buildTestString.Append("IvoCard-000-000-0000-")
buildTestString.Append(addItemsCount)
m_data_creditCards(addItemsCount) = _
buildTestString.ToString()
Next
'Добавить элемент, поиск которого мы хотим выполнить в нашем тесте.
'Выбрать день для значения в первом столбце данных
m_data_travelDates(DUMMY_ROWS_OF_DATA) = _
System.DateTime.Today
'Строка для второго столбца данных
m_data_names(DUMMY_ROWS OF DATA) = "Ms. TestPerson"
'Строка с идентификатором кредитной карточки
m_data_creditCards(DUMMY_ROWS_OF_DATA) = TEST_CREDIT_CARD
End Sub
'–
'Выполнить тест.
'–
Sub changeDayOfTravel_test()
'Отобразить курсор ожидания
System.Windows.Forms.Cursor.Current = _
System.Windows.Forms.Cursors.WaitCursor
'Начать с известной даты.
Dim newDate As System.DateTime newDate = System.DateTime.Today
changeDayOfTravel_CustomArrays(TEST_CREDIT_CARD, newDate)
'ТОЛЬКО В ЦЕЛЯХ ТЕСТИРОВАНИЯ!!!
'HE СЛЕДУЕТ использовать вызовы сборщика мусора в готовом программном
'коде. Это ЗАМЕДЛЯЕТ работу приложения.
System.GC.Collect()
Const testNumber As Integer = 0
'Запустить таймер теста
PerformanceSampling.StartSample(testNumber, "Custom Array implementation")
'Запустить тест!
Dim testCount As Integer
For testCount = 1 To NUMBER_TEST_ITERATIONS
'Передвинуть дату вперед на один день
newDate = newDate.AddDays(1)
Dim numberRecordsChanged As Integer
'Просмотреть все имена, используя СТРОКИ
numberRecordsChanged = _
changeDayOfTravel_CustomArrays(ТЕST_CREDIT_CARD, newDate)
'Убедиться в нормальном выполнении теста
If (numberRecordsChanged <> 1) Then
MsgBox("No matching records found. Test aborted!")
Return
End If
Next
'Получить время выполнения теста
PerformanceSampling.StopSample(testNumber)
'Обычный курсор
System.Windows.Forms.Cursor.Current = _
System.Windows.Forms.Cursors.Default
'Отобразить результаты теста
Dim runInfo As String = NUMBER_TEST_ITERATIONS.ToString() + _
"x" + DUMMY_ROWS_OF_DATA.ToString() + ": " MsgBox(runInfo + _
PerformanceSampling.GetSampleDurationText(testNumber))
End Sub
Private Function changeDayOfTravel_CustomArrays( _
ByVal creditCardNumber As String, ByVal newTravelDate _
As System.DateTime) As Integer
Dim numberRecordsChanged As Integer
'Просмотреть каждый элемент массива
Dim index As Integer
For index = 0 To DUMMY_ROWS_OF_DATA
Dim currentCreditCard As String
currentCreditCard = m_data_creditCards(index)
'Обновить запись при наличии совпадения
If (creditCardNumber = currentCreditCard) Then
'Изменить дату поездки
Dim currentTravelDate As System.DateTime = _
m_data_travelDates(index)
'Увеличить значение счетчика обновлений только при несовпадении данных
If (currentTravelDate <> newTravelDate) Then
m_data_travelDates(index) = _
newTravelDate
numberRecordsChanged = numberRecordsChanged + 1
End If
End If
Next
'Возвратить количество обновленных записей
Return numberRecordsChanged
End Function
Private Sub buttonRunTest_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles buttonRunTest.Click
createDataSet()
changeDayOfTravel_test()
End Sub
Листинг 14.5. Пример пользовательского управления данными – код, помещаемый в форму Form1.cs
'Создает базу данных
Private Sub buttonCreateDatabase_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles buttonCreateDatabase.Click
DatabaseAccess.CreateAndFillDatabase()
End Sub
'Загружает данные из базы данных и отображает их
Private Sub buttonLoadGameData_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles buttonLoadGameData.Click
'Очистить текстовое окно
TextBox1.Text = ""
'Загрузить данные для слов
GameData.InitializeGameVocabulary()
'Обойти все слова и добавить их в текстовый список
Dim thisStringBuilder As System.Text.StringBuilder
thisStringBuilder = New System.Text.StringBuilder
Dim thisWord As VocabularyWord
For Each thisWord In GameData.AllWords
thisStringBuilder.Append(thisWord.EnglishWord)
thisStringBuilder.Append(" = ")
thisStringBuilder.Append( _
thisWord.GermanWordWithArticleIfExists)
thisStringBuilder.Append(vbCrLf) 'Новая строка
Next
'Отобразить список слов в текстовом окне
TextBox1.Text = thisStringBuilder.ToString()
End Sub
Листинг 14.6. Пример кода управления данными для DatabaseAccess.cs
Option Strict On
'–
'Код доступа к базе данных: Этот класс управляет доступом в
'базу данных наших приложений
'–
Imports System
Friend Class DatabaseAccess
Const DATABASE_NAME As String = "LearnGerman.sdf"
Const CONNECT_STRING As String = _
"Data Source = " + DATABASE_NAME + "; Password = ''"
Const TRANSLATIONTABLE_NAME As String = "TranslationDictionary"
Const TRANSLATIONTABLE_ENGLISH_COLUMN As String = "EnglishWord"
Const TRANSLATIONTABLE_GERMAN_COLUMN As String = "GermanWord"
Const TRANSLATIONTABLE_GERMANGENDER_COLUMN As String = "GermanGender"
Const TRANSLATIONTABLE_WORDFUNCTION_COLUMN As String = "WordFunction"
Friend Const DS_WORDS_COLUMNINDEX_ENGLISHWORD As Integer = 0
Friend Const DS_WORDS_COLUMNINDEX_GERMANWORD As Integer = 1
Friend Const DS_WORDS_COLUMNINDEX_GERMANGENDER As Integer = 2
Friend Const DS_WORDS_COLUMNINDEX_WORDFUNCTION As Integer = 3
Public Shared Function GetListOfWords() As _
System.Data.IDataReader
Dim conn As System.Data.SqlServerCe.SqlCeConnection = Nothing
conn = New System.Data.Sq]ServerCe.SqlCeConnection( _
CONNECT_STRING)
conn.Open()
Dim cmd As System.Data.SqlServerCe.SqlCeCommand = _
conn.CreateCommand()
cmd.CommandText = "select " + _
TRANSLATIONTABLE_ENGLISH_COLUMN + ", " _
+ TRANSLATIONTABLE_GERMAN_COLUMN + ", " _
+ TRANSLATIONTABLE_GERMANGENDER_COLUMN + ", " _
+ TRANSLATIONTABLE_WORDFUNCTION_COLUMN + " " _
+ "from " + TRANSLATIONTABLE_NAME
'Выполнить команду базы данных
Dim myReader As System.Data.SqlServerCe.SqlCeDataReader = _
cmd.ExecuteReader(System.Data.CommandBehavior.SingleResult)
Return myReader
End Function
'–
'Создает базу данных в случае необходимости
'–
Public Shared Sub CreateDatabaseIfNonExistant()
If (System.IO.File.Exists(DATABASE_NAME) = False) Then
CreateAndFillDatabase()
End If
End Sub
'–
'Создает и наполняет данными базу данных
'–
Public Shared Sub CreateAndFillDatabase()
'Удалить базу данных, если она уже существует
If (System.IO.File.Exists(DATABASE_NAME)) Then
System.IO.File.Delete(DATABASE_NAME)
End If
'Создать новую базу данных
Dim sqlCeEngine As System.Data.SqlServerCe.SqlCeEngine
sqlCeEngine = New System.Data.SqlServerCe.SqlCeEngine( _
CONNECT_STRING)
sqlCeEngine.CreateDatabase()
'–
'Попытаться подключиться к базе данных
'и наполнить ее данными
'–
Dim conn As System.Data.SqlServerCe.SqlCeConnection = Nothing
Try
conn = New System.Data.SqlServerCe.SqlCeConnection( _
CONNECT_STRING)
conn.Open()
Dim cmd As System.Data.SqlServerCe.SqlCeCommand = _
conn.CreateCommand()
'Создает таблицу перевода
'Поля:
' 1. Слова на английском языке (English)
' 2. Слова на немецком языке (German)
' 3. Грамматический род (Gender)
' 4. Тип слова
cmd.CommandText = "CREATE TABLE " + TRANSLATIONTABLE_NAME _
+ " (" + _
TRANSLATIONTABLE_ENGLISH_COLUMN + " ntext" + ", " + _
TRANSLATIONTABLE_GERMAN COLUMN + " ntext" + ", " + _
TRANSLATIONTABLE_GERMANGENDER_COLUMN + " int" + ", " + _
TRANSLATIONTABLE_WORDFUNCTION_COLUMN + " int" + ")"
cmd.ExecuteNonQuery()
'Наполнить базу данных словами
FillDictionary(cmd)
Catch eTableCreate As System.Exception
MsgBox("Error occured adding table :" + eTableCreate.ToString())
Finally
'Всегда закрывать базу данных по окончании работы
conn.Close()
End Try
'Информировать пользователя о создании базы данных
MsgBox("Created language database!")
End Sub
Private Shared Sub FillDictionary( _
ByVal cmd As System.Data.SqlServerCe.SqlCeCommand)
'Глаголы
InsertEnglishGermanWordPair(cmd, "to pay", "zahlen", _
VocabularyWord.WordGender.notApplicable, _
VocabularyWord.WordFunction.Verb)
InsertEnglishGermanWordPair(cmd, "to catch", "fangen", _
VocabularyWord.WordGender.notApplicable, _
VocabularyWord.WordFunction.Verb)
'Добавить другие слова.
'Местоимения
InsertEnglishGermanWordPair(cmd, "What", "was", _
VocabularyWord.WordGender.notApplicable, _
VocabularyWord.WordFunction.Pronoun)
'Добавить другие слова.
'Наречия
InsertEnglishGermanWordPair(cmd, "where", "wo", _
VocabularyWord.WordGender.notApplicable, _
VocabularyWord.WordFunction.Adverb)
InsertEnglishGermanWordPair(cmd, "never", "nie", _
VocabularyWord.WordGender.notApplicable, _
VocabularyWord.WordFunction.Adverb)
'Добавить другие слова.
'Предлоги
InsertEnglishGermanWordPair(cmd, "at the", "am", _
VocabularyWord.WordGender.notApplicable, _
VocabularyWord.WordFunction.Preposition)
'Имена прилагательные
InsertEnglishGermanWordPair(cmd, "invited", "eingeladen", _
VocabularyWord.WordGender.notApplicable, _
VocabularyWord.WordFunction.Verb)
InsertEnglishGermanWordPair(cmd, "yellow", "gelbe", _
VocabularyWord.WordGender.notApplicable, _
VocabularyWord.WordFunction.Adjective)
InsertEnglishGermanWordPair(cmd, "one", "eins", _
VocabularyWord.WordGender.notApplicable, _
VocabularyWord.WordFunction.Adjective)
InsertEnglishGermanWordPair(cmd, "two", "zwei", _
VocabularyWord.WordGender.notApplicable, _
VocabularyWord.WordFunction.Adjective)
'Имена существительные мужского рода
InsertEnglishGermanWordPair(cmd, "Man", "Mann", _
VocabularyWord.WordGender.Masculine, _
VocabularyWord.WordFunction.Noun)
InsertEnglishGermanWordPair(cmd, "Marketplace", "Marktplatz", _
VocabularyWord.WordGender.Masculine, _
VocabularyWord.WordFunction.Noun)
InsertEnglishGermanWordPair(cmd, "Spoon", "Löffel", _
VocabularyWord.WordGender.Masculine, _
VocabularyWord.WordFunction.Noun)
'Имена существительные женского рода
InsertEnglishGermanWordPair(cmd, "Woman", "Frau", _







