Учебник. Создание приложения WinForms для игры «Подбери пару»
Область применения:
Visual Studio Visual Studio для Mac
Visual Studio Code ![]()
В этой серии из четырех учебников вы создадите игру «Подбери пару», в которой игрок должен подобрать пару скрытым значкам.
Используйте сведения из этих учебников, чтобы узнать о том, как выполнять приведенные ниже задачи интегрированной среде разработки (IDE) Visual Studio.
- сохранять объекты, например значки, в объекте List ;
- использовать цикл foreach в C# или цикл For Each в Visual Basic для перебора элементов в списке;
- отслеживать состояние формы с помощью ссылочных переменных;
- создавать обработчик событий, который можно использовать для нескольких объектов;
- создавать таймер, который отсчитывает время и вызывает событие ровно один раз после запуска.
По завершении всех действий ваша игра будет готова к использованию.

В первом учебнике вы узнаете, как:
- создавать проект Visual Studio, который использует Windows Forms;
- добавлять и форматировать элемент макета;
- добавлять и форматировать метки для отображения.
Необходимые компоненты
Для выполнения шагов, описанных в этом учебнике, вам понадобится Visual Studio. Перейдите на страницу загрузки Visual Studio, чтобы получить бесплатную версию.
Создание проекта игры «Подбери пару» Windows Forms
Первый шаг в создании игры «Подбери пару» — это создание проекта приложения Windows Forms.
- Откройте Visual Studio.
- В окне запуска выберите Создание нового проекта.

- В окне Создать проект выполните поиск по фразе Windows Forms. Затем выберите пункт Классические в списке Все типы проектов.
- Выберите шаблон Приложение Windows Forms (.NET Framework) для C# или Visual Basic, а затем нажмите Далее.
Примечание. Если шаблон Приложение Windows Forms (.NET Framework) отсутствует, его можно установить из окна Создание проекта. В сообщении Не нашли то, что искали? выберите ссылку Установка других средств и компонентов.
После этого выберите пункт Разработка классических приложений .NET в Visual Studio Installer.
В Visual Studio Installer выберите Изменить. Вам может быть предложено сохранить результаты работы. Выберите Продолжить, чтобы установить рабочую нагрузку.

Visual Studio создает решение для приложения. Решение является контейнером для всех проектов и файлов, необходимых приложению.
На этом этапе Visual Studio отображает пустую форму в конструкторе Windows Forms.
Создание макета для игры
В этом разделе вы создадите для игры сетку «четыре на четыре».
- Щелкните форму, чтобы выбрать конструктор Windows Forms. На этой вкладке для C# считывается файл Form1.cs [Design] и для Visual Basic — Form1.vb [Design]. В окне Свойства задайте следующие значения свойств формы.
- Измените свойство Text с Form1 на Matching Game. Этот текст отображается в верхней части окна игры.
- Задайте размер формы. Вы можете изменить его либо задав для свойства Size значение 550, 550, либо перетягивая угол формы до тех пор, пока вы не увидите правильный размер в нижней части IDE Visual Studio.
- Выберите вкладку Панель элементов в левой части интегрированной среды разработки. Если она не отображается, выберите Представление>Панель элементов в строке меню или нажмите сочетание клавиш Ctrl+Alt+X.
- Перетащите элемент управления TableLayoutPanel из категории Контейнеры на панели элементов или дважды щелкните его. В окне Свойства задайте следующие свойства для панели.
- Задайте для свойства BackColor значение CornflowerBlue. Чтобы задать это свойство, щелкните стрелку рядом со свойством BackColor. В диалоговом окне BackColor выберите Интернет. Выберите CornflowerBlue в списке названий доступных цветов.
Примечание. Цвета упорядочены не по алфавиту, и цвет CornflowerBlue находится в нижней части списка.
Элемент управления TableLayoutPanel теперь представляет собой сетку «четыре на четыре» с 16 квадратными ячейками одинакового размера. Эти строки и столбцы задают места, в которых позже появятся значки.

Добавление и форматирование меток для отображения
В этом разделе вы создадите и отформатируете метки, которые будут отображатся во время игры.
- Убедитесь, что TableLayoutPanel выбран в редакторе формы. Вы должны увидеть элемент управления tableLayoutPanel1 в верхней части окна Свойства. Если он не выбран, выберите элемент управления TableLayoutPanel в форме или из списка в верхней части окна Свойства.
- Откройте панель элементов, как и прежде, а затем — категорию Стандартные элементы управления. Добавьте элемент управления Label в верхнюю левую ячейку TableLayoutPanel. Теперь элемент управления label выбран в интегрированной среде разработки. Задайте для него следующие свойства.
- Задайте для свойства BackColor метки значение CornflowerBlue.
- Задайте свойству AutoSize значение False.
- Задайте для свойства Dock значение Fill.
- Задайте для свойства TextAlign значение MiddleCenter, нажав кнопку раскрывающегося списка рядом со свойством, а затем щелкнув среднюю кнопку. Это значение необходимо, чтобы значок отображался в середине ячейки.
- Выберите свойство Font. Появится кнопка с многоточием (…). Нажмите многоточие и задайте для параметра Font значение Webdings, для параметра Font Style — значение Bold, а для параметра Size — значение 48.
- Установите свойство Text равным букве с.
Теперь в левой верхней ячейке TableLayoutPanel располагается черный квадрат на синем фоне, который выравнивается по центру.
Webdings — шрифт значков, который поставляется с операционной системой Windows. В игре «Подбери пару» игроку нужно подобрать пару для значков. Этот шрифт отображает значки, для которых нужно подобрать пары.
Вместо c попробуйте использовать в свойстве Text разные буквы. Восклицательный знак соответствует пауку, прописная буква N — глазу, а запятая — перцу чили.
Этот шаг завершает создание макета вашей формы.

Следующие шаги
Перейдите к следующему учебнику, чтобы узнать, как назначать случайные значки каждой метке и добавлять в метки обработчики событий.
Как автоматизировать Excel с помощью Visual C# для заполнения или получения данных в диапазоне с помощью массивов
В этой статье показано, как автоматизировать Microsoft Excel с помощью Microsoft Visual C# 2005 или Microsoft Visual C# .NET для заполнения и извлечения значений в диапазоне с несколькими ячейками с помощью массивов.
Дополнительная информация
Чтобы заполнить диапазон с несколькими ячейками, не заполняя ячейки по одному, можно задать для свойства Value объекта Range двумерный массив. Аналогичным образом можно получить двумерный массив значений для нескольких ячеек одновременно с помощью свойства Value. Следующие шаги демонстрируют этот процесс как для настройки, так и для извлечения данных с помощью двумерных массивов.
Создание клиента автоматизации для Microsoft Excel
- Запустите Microsoft Visual Studio 2005 или Microsoft Visual Studio .NET.
- В меню Файл выберите команду Создать, а затем выберите Проект. Выберите приложение Windows в типах проектов Visual C#. Form1 создается по умолчанию.
- Добавьте ссылку на библиотеку объектов Microsoft Excel 11.0 в Visual Studio 2005 или библиотеку объектов Microsoft Excel в Visual Studio .NET. Для этого выполните следующие действия:
- On the Project menu, click Add Reference.
- На вкладке COM найдите библиотеку объектов Microsoft Excel и нажмите кнопку «Выбрать».
В Visual Studio 2005 найдите библиотеку объектов Microsoft Excel 11.0 на вкладке COM .
Примечание Microsoft Office 2003 включает основные сборки взаимодействия (PIA). Microsoft Office XP не включает персональные данные, но их можно скачать.
private void button1_Click(object sender, System.EventArgs e)
//Declare these two variables globally so you can access them from both //Button1 and Button2. Excel.Application objApp; Excel._Workbook objBook; private void button1_Click(object sender, System.EventArgs e) < Excel.Workbooks objBooks; Excel.Sheets objSheets; Excel._Worksheet objSheet; Excel.Range range; try < // Instantiate Excel and start a new workbook. objApp = new Excel.Application(); objBooks = objApp.Workbooks; objBook = objBooks.Add( Missing.Value ); objSheets = objBook.Worksheets; objSheet = (Excel._Worksheet)objSheets.get_Item(1); //Get the range where the starting cell has the address //m_sStartingCell and its dimensions are m_iNumRows x m_iNumCols. range = objSheet.get_Range("A1", Missing.Value); range = range.get_Resize(5, 5); if (this.FillWithStrings.Checked == false) < //Create an array. double[,] saRet = new double[5, 5]; //Fill the array. for (long iRow = 0; iRow < 5; iRow++) < for (long iCol = 0; iCol < 5; iCol++) < //Put a counter in the cell. saRet[iRow, iCol] = iRow * iCol; >> //Set the range value to the array. range.set_Value(Missing.Value, saRet ); > else < //Create an array. string[,] saRet = new string[5, 5]; //Fill the array. for (long iRow = 0; iRow < 5; iRow++) < for (long iCol = 0; iCol < 5; iCol++) < //Put the row and column address in the cell. saRet[iRow, iCol] = iRow.ToString() + "|" + iCol.ToString(); >> //Set the range value to the array. range.set_Value(Missing.Value, saRet ); > //Return control of Excel to the user. objApp.Visible = true; objApp.UserControl = true; > catch( Exception theException ) < String errorMessage; errorMessage = "Error: "; errorMessage = String.Concat( errorMessage, theException.Message ); errorMessage = String.Concat( errorMessage, " Line: " ); errorMessage = String.Concat( errorMessage, theException.Source ); MessageBox.Show( errorMessage, "Error" ); >>private void button2_Click(object sender, System.EventArgs e)
private void button2_Click(object sender, System.EventArgs e) < Excel.Sheets objSheets; Excel._Worksheet objSheet; Excel.Range range; try < try < //Get a reference to the first sheet of the workbook. objSheets = objBook.Worksheets; objSheet = (Excel._Worksheet)objSheets.get_Item(1); >catch( Exception theException ) < String errorMessage; errorMessage = "Can't find the Excel workbook. Try clicking Button1 " + "to create an Excel workbook with data before running Button2."; MessageBox.Show( errorMessage, "Missing Workbook?"); //You can't automate Excel if you can't find the data you created, so //leave the subroutine. return; >//Get a range of data. range = objSheet.get_Range("A1", "E5"); //Retrieve the data from the range. Object[,] saRet; saRet = (System.Object[,])range.get_Value( Missing.Value ); //Determine the dimensions of the array. long iRows; long iCols; iRows = saRet.GetUpperBound(0); iCols = saRet.GetUpperBound(1); //Build a string that contains the data of the array. String valueString; valueString = "Array Data\n"; for (long rowCounter = 1; rowCounter //Write in a new line. valueString = String.Concat(valueString, "\n"); > //Report the value of the array. MessageBox.Show(valueString, "Array Values"); > catch( Exception theException ) < String errorMessage; errorMessage = "Error: "; errorMessage = String.Concat( errorMessage, theException.Message ); errorMessage = String.Concat( errorMessage, " Line: " ); errorMessage = String.Concat( errorMessage, theException.Source ); MessageBox.Show( errorMessage, "Error" ); >>- Прокрутите страницу до верхней части окна кода. Добавьте следующую строку в конец списка директив using:
using System.Reflection; using Excel = Microsoft.Office.Interop.Excel;Тестирование клиента службы автоматизации
- Нажмите клавишу F5, чтобы выполнить сборку и запуск примера программы.
- Нажмите кнопку1. Программа запускает Microsoft Excel с новой книгой и заполняет ячейки A1:E5 первого листа числовыми данными из массива.
- Нажмите кнопку «Кнопка2». Программа извлекает данные из ячеек A1:E5 в новый массив и отображает результаты в окне сообщения.
- Выберите FillWithStrings и нажмите кнопку Button1, чтобы заполнить ячейки A1:E5 строковыми данными.
Ссылки
Дополнительные сведения см. на следующем веб-сайте Microsoft Developer Network (MSDN):
Создание простого приложения для работы с данными с помощью ADO.NET
Область применения:
Visual Studio Visual Studio для Mac
Visual Studio Code 
Наборы данных и связанные классы являются устаревшими технологиями платформа .NET Framework с начала 2000-х годов, которые позволяют приложениям работать с данными в памяти во время отключения приложений от базы данных. Они особенно полезны для приложений, которые позволяют пользователям изменять данные и сохранять изменения обратно в базу данных. Хотя наборы данных оказались очень успешными, мы рекомендуем новым приложениям .NET использовать Entity Framework Core. Entity Framework предоставляет более естественный способ работы с табличными данными в виде объектных моделей, и он имеет более простой интерфейс программирования.
При создании приложения, которое работает с данными в базе данных, необходимо выполнить такие основные задачи, как определение строк подключения, вставка данных и выполнение хранимых процедур. Следуя этому разделу, вы можете узнать, как взаимодействовать с базой данных из простого приложения Windows Forms по данным с помощью Visual C# или Visual Basic и ADO.NET. Все технологии данных .NET, включая наборы данных, LINQ to SQL и Entity Framework, в конечном счете выполняют действия, которые очень похожи на приведенные в этой статье.
В этой статье демонстрируется простой способ быстрого получения данных из базы данных. Если приложению необходимо изменить данные в нетривиальных способах и обновить базу данных, следует рассмотреть возможность использования Entity Framework и использования привязки данных для автоматической синхронизации элементов управления пользовательским интерфейсом с изменениями в базовых данных.
С целью упрощения код не включает обработку исключений для выполнения в рабочей среде.
Полный код для этого руководства можно получить в репозитории GitHub в Visual Studio в C# и Visual Basic.
Необходимые компоненты
Чтобы создать приложение, вам потребуется:
- Visual Studio с установленными рабочими нагрузками разработки классических приложений .NET и хранилища данных и обработки. Чтобы установить их, откройте Visual Studio Installer и нажмите кнопку «Изменить» (или «Изменить >«) рядом с версией Visual Studio, которую вы хотите изменить.
- SQL Server Express LocalDB. Если у вас нет SQL Server Express LocalDB, его можно установить на странице загрузки SQL Server.
В этом разделе предполагается, что вы знакомы с основными функциями интегрированной среды разработки Visual Studio и можете создавать приложения Windows Forms, добавлять формы в проект, помещать кнопки и другие элементы управления в формы, задавать свойства элементов управления и кодировать простые события. Если вы не знакомы с этими задачами, мы рекомендуем завершить создание приложения Windows Forms в Visual Studio с помощью руководства по Visual Basic или создать приложение Windows Forms в Visual Studio с помощью руководства по C# , прежде чем начать это пошаговое руководство.
Настройка образца базы данных
Создайте образец базы данных, выполнив следующие действия.
- В Visual Studio откройте окно Обозреватель сервера.
- Щелкните правой кнопкой мыши Подключение данных и выберите «Создать базу данных SQL Server».
- В текстовом поле имени сервера введите (localdb)\mssqllocaldb.
- В текстовом поле «Новое имя базы данных» введите sales, а затем нажмите кнопку «ОК«. Пустая база данных sales создается и добавляется в узел data Подключение ions в сервере Обозреватель.
- Щелкните правой кнопкой мыши подключение к данным о продажах и выберите «Создать запрос«. Откроется окно редактора запросов.
- Скопируйте скрипт Sales Transact-SQL в буфер обмена.
- Вставьте скрипт T-SQL в редактор запросов и нажмите кнопку «Выполнить «. Через некоторое время запрос завершает выполнение и создаются объекты базы данных. База данных содержит две таблицы: Customer и Orders. Эти таблицы изначально не содержат данных, но при запуске создаваемого приложения можно добавить данные. База данных также содержит четыре простых хранимых процедуры.
Создание форм и добавление элементов управления
- Создайте проект C# или Visual Basic с помощью шаблона приложения Windows Forms (платформа .NET Framework), а затем назовите его SimpleDataApp. Visual Studio создает проект и несколько файлов, включая пустую форму Windows Forms с именем Form1.
- Добавьте две формы Windows Forms в проект, чтобы он включал три формы, и назначьте им следующие имена:
- Переходы
- NewCustomer
- FillOrCancel
- Для каждой формы добавьте текстовые поля, кнопки и другие элементы управления, которые отображаются на рисунках ниже. Для каждого элемента управления задайте свойства, указанные в таблицах.
Примечание. Элементы управления «группа» и «надпись» обеспечивают большую ясность, но не используются в коде.
Форма навигации
| Элементы управления формы навигации | Свойства |
|---|---|
| Кнопка | Name = btnGoToAdd |
| Кнопка | Name = btnGoToFillOrCancel |
| Кнопка | Name = btnExit |
Форма NewCustomer

Форма FillOrCancel

Сохранение строки подключения
Когда приложение пытается открыть подключение к базе данных, оно должно иметь доступ к строке подключения. Чтобы избежать ввода строки вручную в каждой форме, сохраните строку в файле App.config в проекте и создайте метод, возвращающий строку при вызове метода из любой формы в приложении.
Вы можете найти строка подключения, щелкнув правой кнопкой мыши подключение к данным о продажах в сервере Обозреватель и выбрав свойства. Найдите свойство Подключение ionString, а затем нажмите клавиши CTRL+A, CTRL+C, чтобы выбрать и скопировать строку в буфер обмена.

- Если вы используете C#, в Обозреватель решений разверните узел свойств в проекте и откройте файл Параметры.settings. Если вы используете Visual Basic, в Обозреватель решений щелкните «Показать все файлы«, разверните узел «Мой проект» и откройте файл Параметры.settings.
- В столбце «Имя» введите connString .
- В списке «Тип« выберите (Подключение ion String).
- В списке областей выберите «Приложение«.
- В столбце «Значение» введите строка подключения (без каких-либо внешних кавычек), а затем сохраните изменения.
В реальном приложении необходимо безопасно хранить строка подключения, как описано в строках Подключение ion и файлах конфигурации.
Написание кода для форм
В этом разделе содержатся краткие сведения о том, что делает каждая форма. Он также предоставляет код, определяющий базовую логику при нажатии кнопки в форме.
Форма навигации
Форма навигации открывается при запуске приложения. Кнопка Добавить учетную запись открывает форму NewCustomer. Кнопка Выполнение или отмена заказов открывает форму FillOrCancel. Кнопка Выход закрывает приложение.
Преобразование формы навигации в начальную форму
При использовании C# в обозревателе решений откройте файл Program.cs и измените строку Application.Run на следующую: Application.Run(new Navigation());
Если вы используете Visual Basic, в Обозреватель решений откройте окно «Свойства«, перейдите на вкладку «Приложение«, а затем выберите SimpleDataApp.Navigation в списке форм запуска.
Создание обработчиков событий автоматического создания
Дважды щелкните три кнопки в форме навигации, чтобы создать пустые методы обработчика событий. Дважды щелкнув кнопки, также добавляет автоматически созданный код в файл кода конструктора, который позволяет нажатию кнопки вызывать событие.
Если вы пропустите действие двойного щелчка в конструкторе и просто скопируйте код и вставьте его в файлы кода, не забудьте задать обработчик событий правильным методом. Это можно сделать в окне «Свойства «. Перейдите на вкладку «События» (используйте кнопку панели инструментов молнии) и найдите обработчик щелчка .
Добавление кода для логики формы навигации
На кодовой странице формы навигации заполните тела методов для трех обработчиков событий нажатия кнопки, как показано в следующем коде.
////// Opens the NewCustomer form as a dialog box, /// which returns focus to the calling form when it is closed. /// private void btnGoToAdd_Click(object sender, EventArgs e) < Form frm = new NewCustomer(); frm.Show(); >////// Opens the FillorCancel form as a dialog box. /// private void btnGoToFillOrCancel_Click(object sender, EventArgs e) < Form frm = new FillOrCancel(); frm.ShowDialog(); >////// Closes the application (not just the Navigation form). /// private void btnExit_Click(object sender, EventArgs e)
''' ''' Opens the NewCustomer form as a dialog box, which returns focus to the calling form when it closes. ''' Private Sub btnGoToAdd_Click(sender As Object, e As EventArgs) Handles btnGoToAdd.Click Dim frm As Form = New NewCustomer() frm.Show() End Sub ''' ''' Opens the FillOrCancel form as a dialog box. ''' Private Sub btnGoToFillOrCancel_Click(sender As Object, e As EventArgs) Handles btnGoToFillOrCancel.Click Dim frm As Form = New FillOrCancel() frm.ShowDialog() End Sub ''' ''' Closes the application (not just the navigation form). ''' Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click Me.Close() End Sub
Код для этого руководства доступен в C# и Visual Basic. Чтобы переключить язык кода на этой странице между C# и Visual Basic, используйте переключатель языка кода в верхней части каждого примера кода.
Форма NewCustomer
При вводе имени клиента и нажатии кнопки «Создать учетную запись » форма NewCustomer создает учетную запись клиента, а SQL Server возвращает значение IDENTITY в качестве нового идентификатора клиента. Затем вы можете разместить заказ для новой учетной записи, указав сумму и дату заказа и нажав кнопку «Заказ места «.
Создание обработчиков событий автоматического создания
Создайте пустой обработчик событий Click для каждой кнопки в форме NewCustomer, дважды щелкнув каждую из четырех кнопок. Дважды щелкнув кнопки, также добавляет автоматически созданный код в файл кода конструктора, который позволяет нажатию кнопки вызывать событие.
Добавление кода для логики формы NewCustomer
Чтобы завершить логику формы NewCustomer, выполните следующие действия.
System.Data.SqlClient Доведите пространство имен в область, чтобы вам не нужно полностью квалифицировать имена его членов.
using System.Data.SqlClient;
Imports System.Data.SqlClient
Добавьте в класс некоторые переменные и вспомогательные методы, как показано в следующем коде.
// Storage for IDENTITY values returned from database. private int parsedCustomerID; private int orderID; ////// Verifies that the customer name text box is not empty. /// private bool IsCustomerNameValid() < if (txtCustomerName.Text == "") < MessageBox.Show("Please enter a name."); return false; >else < return true; >> ////// Verifies that a customer ID and order amount have been provided. /// private bool IsOrderDataValid() < // Verify that CustomerID is present. if (txtCustomerID.Text == "") < MessageBox.Show("Please create customer account before placing order."); return false; >// Verify that Amount isn't 0. else if ((numOrderAmount.Value < 1)) < MessageBox.Show("Please specify an order amount."); return false; >else < // Order can be submitted. return true; >> ////// Clears the form data. /// private void ClearForm()
' Storage for ID values returned from the database. Private parsedCustomerID As Integer Private orderID As Integer ''' ''' Verifies that the customer name text box is not empty. ''' Private ReadOnly Property IsCustomerNameValid As Boolean Get If txtCustomerName.Text = "" Then MessageBox.Show("Please enter a name.") Return False Else Return True End If End Get End Property ''' ''' Verifies the order data is valid. ''' Private Function IsOrderDataValid() As Boolean ' Verify that CustomerID is present. If txtCustomerID.Text = "" Then MessageBox.Show("Please create a customer account before placing order.") Return False ' Verify that order amount isn't 0. ElseIf (numOrderAmount.Value < 1) Then MessageBox.Show("Please specify an order amount.") Return False Else ' Order can be submitted. Return True End If End Function ''' ''' Clears values from controls. ''' Private Sub ClearForm() txtCustomerName.Clear() txtCustomerID.Clear() dtpOrderDate.Value = DateTime.Now numOrderAmount.Value = 0 Me.parsedCustomerID = 0 End Sub
Заполните тела метода для четырех обработчиков событий нажатия кнопки, как показано в следующем коде.
////// Creates a new customer by calling the Sales.uspNewCustomer stored procedure. /// private void btnCreateAccount_Click(object sender, EventArgs e) < if (IsCustomerNameValid()) < // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) < // Create a SqlCommand, and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspNewCustomer", connection)) < sqlCommand.CommandType = CommandType.StoredProcedure; // Add input parameter for the stored procedure and specify what to use as its value. sqlCommand.Parameters.Add(new SqlParameter("@CustomerName", SqlDbType.NVarChar, 40)); sqlCommand.Parameters["@CustomerName"].Value = txtCustomerName.Text; // Add the output parameter. sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int)); sqlCommand.Parameters["@CustomerID"].Direction = ParameterDirection.Output; try < connection.Open(); // Run the stored procedure. sqlCommand.ExecuteNonQuery(); // Customer ID is an IDENTITY value from the database. this.parsedCustomerID = (int)sqlCommand.Parameters["@CustomerID"].Value; // Put the Customer ID value into the read-only text box. this.txtCustomerID.Text = Convert.ToString(parsedCustomerID); >catch < MessageBox.Show("Customer ID was not returned. Account could not be created."); >finally < connection.Close(); >> > > > ////// Calls the Sales.uspPlaceNewOrder stored procedure to place an order. /// private void btnPlaceOrder_Click(object sender, EventArgs e) < // Ensure the required input is present. if (IsOrderDataValid()) < // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) < // Create SqlCommand and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspPlaceNewOrder", connection)) < sqlCommand.CommandType = CommandType.StoredProcedure; // Add the @CustomerID input parameter, which was obtained from uspNewCustomer. sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int)); sqlCommand.Parameters["@CustomerID"].Value = this.parsedCustomerID; // Add the @OrderDate input parameter. sqlCommand.Parameters.Add(new SqlParameter("@OrderDate", SqlDbType.DateTime, 8)); sqlCommand.Parameters["@OrderDate"].Value = dtpOrderDate.Value; // Add the @Amount order amount input parameter. sqlCommand.Parameters.Add(new SqlParameter("@Amount", SqlDbType.Int)); sqlCommand.Parameters["@Amount"].Value = numOrderAmount.Value; // Add the @Status order status input parameter. // For a new order, the status is always O (open). sqlCommand.Parameters.Add(new SqlParameter("@Status", SqlDbType.Char, 1)); sqlCommand.Parameters["@Status"].Value = "O"; // Add the return value for the stored procedure, which is the order ID. sqlCommand.Parameters.Add(new SqlParameter("@RC", SqlDbType.Int)); sqlCommand.Parameters["@RC"].Direction = ParameterDirection.ReturnValue; try < //Open connection. connection.Open(); // Run the stored procedure. sqlCommand.ExecuteNonQuery(); // Display the order number. this.orderID = (int)sqlCommand.Parameters["@RC"].Value; MessageBox.Show("Order number " + this.orderID + " has been submitted."); >catch < MessageBox.Show("Order could not be placed."); >finally < connection.Close(); >> > > > ////// Clears the form data so another new account can be created. /// private void btnAddAnotherAccount_Click(object sender, EventArgs e) < this.ClearForm(); >////// Closes the form/dialog box. /// private void btnAddFinish_Click(object sender, EventArgs e)
''' ''' Creates a new account by executing the Sales.uspNewCustomer ''' stored procedure on the database. ''' Private Sub btnCreateAccount_Click(sender As Object, e As EventArgs) Handles btnCreateAccount.Click ' Ensure a customer name has been entered. If IsCustomerNameValid Then ' Create the SqlConnection object. Using connection As New SqlConnection(My.Settings.connString) ' Create a SqlCommand, and identify the command type as a stored procedure. Using sqlCommand As New SqlCommand("Sales.uspNewCustomer", connection) sqlCommand.CommandType = CommandType.StoredProcedure ' Add the customer name input parameter for the stored procedure. sqlCommand.Parameters.Add(New SqlParameter("@CustomerName", SqlDbType.NVarChar, 40)) sqlCommand.Parameters("@CustomerName").Value = txtCustomerName.Text ' Add the customer ID output parameter. sqlCommand.Parameters.Add(New SqlParameter("@CustomerID", SqlDbType.Int)) sqlCommand.Parameters("@CustomerID").Direction = ParameterDirection.Output Try ' Open the connection. connection.Open() ' Run the stored procedure. sqlCommand.ExecuteNonQuery() ' Convert the Customer ID value to an Integer. Me.parsedCustomerID = CInt(sqlCommand.Parameters("@CustomerID").Value) ' Insert the customer ID into the corresponding text box. Me.txtCustomerID.Text = Convert.ToString(parsedCustomerID) Catch MessageBox.Show("Customer ID was not returned. Account could not be created.") Finally ' Close the connection. connection.Close() End Try End Using End Using End If End Sub ''' ''' Places the order by executing the Sales.uspPlaceNewOrder ''' stored procedure on the database. ''' Private Sub btnPlaceOrder_Click(sender As Object, e As EventArgs) Handles btnPlaceOrder.Click If IsOrderDataValid() Then ' Create the connection. Using connection As New SqlConnection(My.Settings.connString) ' Create SqlCommand and identify it as a stored procedure. Using sqlCommand As New SqlCommand("Sales.uspPlaceNewOrder", connection) sqlCommand.CommandType = CommandType.StoredProcedure ' Add the @CustomerID parameter, which was an output parameter from uspNewCustomer. sqlCommand.Parameters.Add(New SqlParameter("@CustomerID", SqlDbType.Int)) sqlCommand.Parameters("@CustomerID").Value = Me.parsedCustomerID ' Add the @OrderDate parameter. sqlCommand.Parameters.Add(New SqlParameter("@OrderDate", SqlDbType.DateTime, 8)) sqlCommand.Parameters("@OrderDate").Value = dtpOrderDate.Value ' Add the @Amount parameter. sqlCommand.Parameters.Add(New SqlParameter("@Amount", SqlDbType.Int)) sqlCommand.Parameters("@Amount").Value = numOrderAmount.Value ' Add the @Status parameter. For a new order, the status is always O (open). sqlCommand.Parameters.Add(New SqlParameter("@Status", SqlDbType.[Char], 1)) sqlCommand.Parameters("@Status").Value = "O" ' Add a return value parameter for the stored procedure, which is the orderID. sqlCommand.Parameters.Add(New SqlParameter("@RC", SqlDbType.Int)) sqlCommand.Parameters("@RC").Direction = ParameterDirection.ReturnValue Try ' Open connection. connection.Open() ' Run the stored procedure. sqlCommand.ExecuteNonQuery() ' Display the order number. Me.orderID = CInt(sqlCommand.Parameters("@RC").Value) MessageBox.Show("Order number " & (Me.orderID).ToString & " has been submitted.") Catch ' A simple catch. MessageBox.Show("Order could not be placed.") Finally ' Always close a connection after you finish using it, ' so that it can be released to the connection pool. connection.Close() End Try End Using End Using End If End Sub ''' ''' Resets the form for another new account. ''' Private Sub btnAddAnotherAccount_Click(sender As Object, e As EventArgs) Handles btnAddAnotherAccount.Click Me.ClearForm() End Sub ''' ''' Closes the NewCustomer form and returns focus to the Navigation form. ''' Private Sub btnAddFinish_Click(sender As Object, e As EventArgs) Handles btnAddFinish.Click Me.Close() End Sub
Форма FillOrCancel
Форма FillOrCancel запускает запрос, чтобы вернуть заказ при вводе идентификатора заказа, а затем нажмите кнопку «Найти заказ «. Возвращенная строка отображается в сетке данных только для чтения. Вы можете пометить заказ как отмененный (X), если нажмите кнопку «Отмена заказа «, или вы можете пометить заказ как заполненный (F) при нажатии кнопки «Заказ заполнения «. Если снова выбрать кнопку «Найти заказ «, появится обновленная строка.
Создание обработчиков событий автоматического создания
Создайте пустые обработчики событий Click для четырех кнопок в форме FillOrCancel, дважды щелкнув кнопки. Дважды щелкнув кнопки, также добавляет автоматически созданный код в файл кода конструктора, который позволяет нажатию кнопки вызывать событие.
Добавление кода для логики формы FillOrCancel
Чтобы завершить логику формы FillOrCancel, выполните следующие действия.
Доведите следующие два пространства имен в область, чтобы вам не нужно полностью указать имена своих членов.
using System.Data.SqlClient; using System.Text.RegularExpressions;
Imports System.Data.SqlClient Imports System.Text.RegularExpressions
Добавьте в класс переменную и вспомогательный метод, как показано в следующем коде.
// Storage for the order ID value. private int parsedOrderID; /// /// Verifies that an order ID is present and contains valid characters. /// private bool IsOrderIDValid() < // Check for input in the Order ID text box. if (txtOrderID.Text == "") < MessageBox.Show("Please specify the Order ID."); return false; >// Check for characters other than integers. else if (Regex.IsMatch(txtOrderID.Text, @"^\D*$")) < // Show message and clear input. MessageBox.Show("Customer ID must contain only numbers."); txtOrderID.Clear(); return false; >else < // Convert the text in the text box to an integer to send to the database. parsedOrderID = Int32.Parse(txtOrderID.Text); return true; >>
' Storage for OrderID. Private parsedOrderID As Integer ''' ''' Verifies that OrderID is valid. ''' Private Function IsOrderIDValid() As Boolean ' Check for input in the Order ID text box. If txtOrderID.Text = "" Then MessageBox.Show("Please specify the Order ID.") Return False ' Check for characters other than integers. ElseIf Regex.IsMatch(txtOrderID.Text, "^\D*$") Then ' Show message and clear input. MessageBox.Show("Please specify integers only.") txtOrderID.Clear() Return False Else ' Convert the text in the text box to an integer to send to the database. parsedOrderID = Int32.Parse(txtOrderID.Text) Return True End If End Function
Заполните тела метода для четырех обработчиков событий нажатия кнопки, как показано в следующем коде.
////// Executes a t-SQL SELECT statement to obtain order data for a specified /// order ID, then displays it in the DataGridView on the form. /// private void btnFindByOrderID_Click(object sender, EventArgs e) < if (IsOrderIDValid()) < using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) < // Define a t-SQL query string that has a parameter for orderID. const string sql = "SELECT * FROM Sales.Orders WHERE orderID = @orderID"; // Create a SqlCommand object. using (SqlCommand sqlCommand = new SqlCommand(sql, connection)) < // Define the @orderID parameter and set its value. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; try < connection.Open(); // Run the query by calling ExecuteReader(). using (SqlDataReader dataReader = sqlCommand.ExecuteReader()) < // Create a data table to hold the retrieved data. DataTable dataTable = new DataTable(); // Load the data from SqlDataReader into the data table. dataTable.Load(dataReader); // Display the data from the data table in the data grid view. this.dgvCustomerOrders.DataSource = dataTable; // Close the SqlDataReader. dataReader.Close(); >> catch < MessageBox.Show("The requested order could not be loaded into the form."); >finally < // Close the connection. connection.Close(); >> > > > ////// Cancels an order by calling the Sales.uspCancelOrder /// stored procedure on the database. /// private void btnCancelOrder_Click(object sender, EventArgs e) < if (IsOrderIDValid()) < // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) < // Create the SqlCommand object and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspCancelOrder", connection)) < sqlCommand.CommandType = CommandType.StoredProcedure; // Add the order ID input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; try < // Open the connection. connection.Open(); // Run the command to execute the stored procedure. sqlCommand.ExecuteNonQuery(); >catch < MessageBox.Show("The cancel operation was not completed."); >finally < // Close connection. connection.Close(); >> > > > ////// Fills an order by calling the Sales.uspFillOrder stored /// procedure on the database. /// private void btnFillOrder_Click(object sender, EventArgs e) < if (IsOrderIDValid()) < // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) < // Create command and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspFillOrder", connection)) < sqlCommand.CommandType = CommandType.StoredProcedure; // Add the order ID input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; // Add the filled date input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@FilledDate", SqlDbType.DateTime, 8)); sqlCommand.Parameters["@FilledDate"].Value = dtpFillDate.Value; try < connection.Open(); // Execute the stored procedure. sqlCommand.ExecuteNonQuery(); >catch < MessageBox.Show("The fill operation was not completed."); >finally < // Close the connection. connection.Close(); >> > > > ////// Closes the form. /// private void btnFinishUpdates_Click(object sender, EventArgs e)
''' ''' Executes a t-SQL SELECT query on the database to ''' obtain order data for a specified order ID. ''' Private Sub btnFindByOrderID_Click(sender As Object, e As EventArgs) Handles btnFindByOrderID.Click ' Prepare the connection and the command. If IsOrderIDValid() Then ' Create the connection. Using connection As New SqlConnection(My.Settings.connString) ' Define the query string that has a parameter for orderID. Const sql As String = "select * from Sales.Orders where orderID = @orderID" ' Create a SqlCommand object. Using sqlCommand As New SqlCommand(sql, connection) ' Define the @orderID parameter and its value. sqlCommand.Parameters.Add(New SqlParameter("@orderID", SqlDbType.Int)) sqlCommand.Parameters("@orderID").Value = parsedOrderID Try ' Open connection. connection.Open() ' Execute the query. Dim dataReader As SqlDataReader = sqlCommand.ExecuteReader() ' Create a data table to hold the retrieved data. Dim dataTable As New DataTable() ' Load the data from SqlDataReader into the data table. dataTable.Load(dataReader) ' Display the data from the data table in the data grid view. Me.dgvCustomerOrders.DataSource = dataTable ' Close the SqlDataReader. dataReader.Close() Catch MessageBox.Show("The requested order could not be loaded into the form.") Finally ' Close the connection. connection.Close() End Try End Using End Using End If End Sub ''' ''' Fills an order by running the Sales.uspFillOrder stored procedure on the database. ''' Private Sub btnFillOrder_Click(sender As Object, e As EventArgs) Handles btnFillOrder.Click ' Set up and run stored procedure only if OrderID is valid. If IsOrderIDValid() Then ' Create the connection. Using connection As New SqlConnection(My.Settings.connString) ' Create command and identify it as a stored procedure. Using sqlCommand As New SqlCommand("Sales.uspFillOrder", connection) sqlCommand.CommandType = CommandType.StoredProcedure ' Add input parameter for the stored procedure. sqlCommand.Parameters.Add(New SqlParameter("@orderID", SqlDbType.Int)) sqlCommand.Parameters("@orderID").Value = parsedOrderID ' Add second input parameter. sqlCommand.Parameters.Add(New SqlParameter("@FilledDate", SqlDbType.DateTime, 8)) sqlCommand.Parameters("@FilledDate").Value = dtpFillDate.Value Try ' Open the connection. connection.Open() ' Run the SqlCommand. sqlCommand.ExecuteNonQuery() Catch ' A simple catch. MessageBox.Show("The fill operation was not completed.") Finally ' Close the connection. connection.Close() End Try End Using End Using End If End Sub ''' ''' Cancels an order by running the Sales.uspCancelOrder stored procedure on the database. ''' Private Sub btnCancelOrder_Click(sender As Object, e As EventArgs) Handles btnCancelOrder.Click ' Set up and run the stored procedure only if OrderID is ready. If IsOrderIDValid() Then ' Create the connection. Using connection As New SqlConnection(My.Settings.connString) ' Create the command and identify it as a stored procedure. Using sqlCommand As New SqlCommand("Sales.uspCancelOrder", connection) sqlCommand.CommandType = CommandType.StoredProcedure ' Add input parameter for the stored procedure. sqlCommand.Parameters.Add(New SqlParameter("@orderID", SqlDbType.Int)) sqlCommand.Parameters("@orderID").Value = parsedOrderID Try ' Open the connection. connection.Open() ' Run the SqlCommand. sqlCommand.ExecuteNonQuery() Catch ' A simple catch. MessageBox.Show("The cancel operation was not completed.") Finally ' Close connection. connection.Close() End Try End Using End Using End If End Sub ''' ''' Closes the form and returns focus to the Navigation form. ''' Private Sub btnFinishUpdates_Click(sender As Object, e As EventArgs) Handles btnFinishUpdates.Click Me.Close() End Sub
Тестирование приложения
Запустите приложение и попробуйте создать несколько клиентов и заказов, чтобы убедиться, что все работает должным образом. Чтобы убедиться, что база данных обновлена с изменениями, откройте узел таблиц на сервере Обозреватель, щелкните правой кнопкой мыши узлы «Клиенты и заказы» и выберите «Показать данные таблицы».
См. также
Часть 1. Начало работы с XAML
Файл кода программной части обеспечивает поддержку кода для разметки. Вместе эти два файла вносят свой вклад в новое определение класса, которое включает дочерние представления и инициализацию свойств. В XAML-файле классы и свойства ссылаются с помощью XML-элементов и атрибутов, а также устанавливаются связи между разметкой и кодом.
Создание решения
Чтобы начать редактирование первого файла XAML, используйте Visual Studio или Visual Studio для Mac для создания нового Xamarin.Forms решения. (Выберите вкладку ниже, соответствующую вашей среде.)
- Visual Studio
- Visual Studio для Mac
В Windows запустите Visual Studio 2019 и в окне запуска щелкните Создать проект , чтобы создать новый проект:

В окне Создать проект в раскрывающемся списке Тип проекта выберите Мобильное приложение, а затем выберите шаблон Мобильное приложение (Xamarin.Forms) и нажмите кнопку Далее:

В окне Настройка нового проекта задайте имя проектаXamlSamples (или любой другой вариант) и нажмите кнопку Создать .
В диалоговом окне Создание кроссплатформенного приложения нажмите кнопку Пусто и нажмите кнопку ОК :

В решении создаются четыре проекта: библиотека XamlSamples .NET Standard, XamlSamples.Android, XamlSamples.iOS и решение универсальная платформа Windows XamlSamples.UWP.
В Visual Studio для Mac выберите в меню Файл > Новое решение. В диалоговом окне Новый проект выберите Многоплатформенное > приложение слева и Пустое приложение форм (неПриложение Форм) в списке шаблонов:

Нажмите кнопку Далее.
В следующем диалоговом окне присвойте проекту имя XamlSamples (или любой другой вариант). Убедитесь, что выбран переключатель Использовать .NET Standard :

Нажмите кнопку Далее.
В следующем диалоговом окне можно выбрать расположение для проекта:

Нажмите кнопку Создать.
В решении создаются три проекта: библиотека XamlSamples .NET Standard, XamlSamples.Android и XamlSamples.iOS.
После создания решения XamlSamples может потребоваться протестировать среду разработки, выбрав различные проекты платформы в качестве проекта запуска решения, а также создав и развернув простое приложение, созданное с помощью шаблона проекта, на эмуляторах телефона или на реальных устройствах.
Если вам не нужно писать код для конкретной платформы, общий проект библиотеки XamlSamples .NET Standard — это место, где вы будете тратить практически все время программирования. Эти статьи не будут выходить за пределы этого проекта.
Структура файла XAML
В библиотеке XamlSamples .NET Standard есть пара файлов со следующими именами:
- App.xaml, XAML-файл; И
- App.xaml.cs — файл кода программной части C#, связанный с файлом XAML.
Чтобы увидеть файл кода программной части, щелкните стрелку рядом с App.xaml .
И App.xaml, и App.xaml.cs участвуют в создании класса с именем App , который является производным от Application . Большинство других классов с файлами XAML участвуют в классе, который является производным от ContentPage ; эти файлы используют XAML для определения визуального содержимого всей страницы. Это относится к двум другим файлам в проекте XamlSamples :
- MainPage.xaml, XAML-файл; И
- MainPage.xaml.cs, файл кода программной части C#.
Файл MainPage.xaml выглядит следующим образом (хотя форматирование может немного отличаться):
Два объявления пространства имен XML ( xmlns ) ссылаются на универсальные коды ресурса (URI), первое, по-видимому, на веб-сайте Xamarin, а второе — на сайте Майкрософт. Не беспокойтесь о проверке того, на что указывают эти URI. Там ничего нет. Они являются просто универсальными кодами ресурса (URI), принадлежащими Xamarin и Майкрософт, и в основном функционируют как идентификаторы версий.
Первое объявление пространства имен XML означает, что теги, определенные в XAML-файле без префикса, ссылаются на классы в Xamarin.Forms, например ContentPage . Второе объявление пространства имен определяет префикс x . Он используется для нескольких элементов и атрибутов, которые являются встроенными в самом XAML и поддерживаются другими реализациями XAML. Однако эти элементы и атрибуты немного отличаются в зависимости от года, внедренного в URI. Xamarin.Forms поддерживает спецификацию XAML 2009 года, но не все.
Объявление local пространства имен позволяет получить доступ к другим классам из проекта библиотеки .NET Standard.
В конце этого первого тега x префикс используется для атрибута с именем Class . Поскольку использование этого x префикса является практически универсальным для пространства имен XAML, атрибуты XAML, такие как Class почти всегда называются x:Class .
Атрибут x:Class задает полное имя класса .NET: MainPage класс в XamlSamples пространстве имен. Это означает, что этот XAML-файл определяет новый класс MainPage в XamlSamples пространстве имен, наследуемом от ContentPage — теге, в котором x:Class отображается атрибут .
Атрибут x:Class может отображаться только в корневом элементе XAML-файла для определения производного класса C#. Это единственный новый класс, определенный в XAML-файле. Все остальное, что отображается в XAML-файле, просто создается из существующих классов и инициализируется.
Файл MainPage.xaml.cs выглядит следующим образом (помимо неиспользуемых using директив):
using Xamarin.Forms; namespace XamlSamples < public partial class MainPage : ContentPage < public MainPage() < InitializeComponent(); >> >
Класс MainPage является производным от ContentPage , но обратите внимание на partial определение класса. Это предполагает, что должно быть другое частичное определение класса для MainPage , но где это? И что это InitializeComponent за метод?
Когда Visual Studio создает проект, он анализирует XAML-файл для создания файла кода C#. Если вы посмотрите в каталоге XamlSamples\XamlSamples\obj\Debug , вы найдете файл с именем XamlSamples.MainPage.xaml.g.cs. «g» означает «сгенерированный». Это другое определение разделяемого класса объекта MainPage , которое содержит определение метода, InitializeComponent вызываемого из конструктора MainPage . Затем эти два определения разделяемых MainPage классов можно скомпилировать вместе. В зависимости от того, компилируется xaml или нет, в исполняемый файл внедряется либо XAML-файл, либо двоичный файл XAML.
Во время выполнения код в проекте конкретной LoadApplication платформы вызывает метод , передавая ему новый экземпляр App класса в библиотеке .NET Standard. Конструктор App класса создает MainPage экземпляр . Конструктор этого класса вызывает InitializeComponent метод , который затем извлекает LoadFromXaml XAML-файл (или его скомпилированный двоичный файл) из библиотеки .NET Standard. LoadFromXaml инициализирует все объекты, определенные в XAML-файле, соединяет их все вместе в отношениях «родители-потомки», присоединяет обработчики событий, определенные в коде, к событиям, заданным в XAML-файле, и задает результирующий дерево объектов в качестве содержимого страницы.
Хотя обычно вам не нужно тратить много времени на созданные файлы кода, иногда исключения среды выполнения создаются для кода в созданных файлах, поэтому вы должны быть знакомы с ними.
При компиляции Label и запуске этой программы элемент отображается в центре страницы, как предполагает XAML:

Для более интересных визуальных элементов вам потребуется более интересный XAML.
Добавление новых страниц XAML
- Visual Studio
- Visual Studio для Mac
Чтобы добавить в проект другие классы на основе ContentPage XAML, выберите проект библиотеки XamlSamples .NET Standard, щелкните правой кнопкой мыши и выберите Добавить > новый элемент. . В диалоговом окне Добавление нового элемента выберите Элемент Visual C# >Xamarin.Forms> Content Page (не Content Page (C#), который создает страницу только для кода или Представление содержимого, которое не является страницей. Присвойте странице имя, например HelloXamlPage:

Чтобы добавить в проект другие классы на основе ContentPage XAML, выберите проект библиотеки XamlSamples .NET Standard и вызовите пункт меню Файл > Создать файл . В левой части диалогового окна Создать файл выберите Формы слева и Forms ContentPage Xaml (не Forms ContentPage, который создает страницу только для кода, или Представление содержимого, которое не является страницей). Присвойте странице имя, например HelloXamlPage:

В проект добавляются два файла: HelloXamlPage.xaml и файл кода программной части HelloXamlPage.xaml.cs.
Настройка содержимого страницы
Измените файл HelloXamlPage.xaml , чтобы единственными тегами были для ContentPage и ContentPage.Content :
Теги ContentPage.Content являются частью уникального синтаксиса XAML. Сначала они могут показаться недопустимыми XML, но они являются законными. Точка не является специальным символом в XML.
Теги ContentPage.Content называются тегами элементов свойств . Content является свойством ContentPage , и обычно устанавливается в одно представление или макет с дочерними представлениями. Обычно свойства становятся атрибутами в XAML, но сложно задать Content атрибут для сложного объекта. По этой причине свойство выражается в виде XML-элемента, состоящего из имени класса и имени свойства, разделенного точкой. Content Теперь свойство можно задать между ContentPage.Content тегами следующим образом:
Также обратите внимание, что для корневого Title тега задан атрибут .
В настоящее время связь между классами, свойствами и XML должна быть очевидной Xamarin.Forms : класс (например ContentPage , или Label ) отображается в XAML-файле в виде XML-элемента. Свойства этого класса, включая Title ContentPage и семь свойств , Label обычно отображаются в виде XML-атрибутов.
Существует множество сочетаний клавиш для задания значений этих свойств. Некоторые свойства являются базовыми типами данных: например, Title свойства и Text имеют тип String , Rotation имеет тип Double , а IsVisible (по true умолчанию и задается здесь только для иллюстрации) имеет тип Boolean .
Свойство HorizontalTextAlignment имеет тип TextAlignment , который является перечислением . Для свойства любого типа перечисления достаточно указать имя члена.
Однако для свойств более сложных типов для синтаксического анализа XAML используются преобразователи. Это классы в Xamarin.Forms , производные от TypeConverter . Многие из них являются публичными классами, но некоторые нет. Для этого конкретного XAML-файла некоторые из этих классов играют определенную роль в фоновом режиме:
- LayoutOptionsConverter VerticalOptions для свойства
- FontSizeConverter FontSize для свойства
- ColorTypeConverter TextColor для свойства
Эти преобразователи управляют допустимым синтаксисом параметров свойства.
Может ThicknessTypeConverter обрабатывать одно, два или четыре числа, разделенные запятыми. Если указано одно число, оно применяется ко всем четырем сторонам. С двумя числами первый — левое и правое заполнение, а второе — сверху и снизу. Четыре числа находятся в порядке слева, сверху, справа и внизу.
Может LayoutOptionsConverter преобразовывать имена открытых статических полей структуры в LayoutOptions значения типа LayoutOptions .
может FontSizeConverter обрабатывать размер NamedSize члена или числового шрифта.
принимает ColorTypeConverter имена общедоступных статических полей Color структуры или шестнадцатеричных значений RGB с альфа-каналом или без него, перед которыми имеется знак числа (#). Ниже приведен синтаксис без альфа-канала:
Каждая из маленьких букв представляет собой шестнадцатеричную цифру. Вот как включается альфа-канал:
Для альфа-канала следует помнить, что FF является полностью непрозрачным, а 00 — полностью прозрачным.
Два других формата позволяют указать только одну шестнадцатеричную цифру для каждого канала:
В таких случаях цифра повторяется для формирования значения. Например, #CF3 цвет RGB CC-FF-33.
Переход по страницам
При запуске программы MainPage XamlSamples отображается . Чтобы просмотреть новую HelloXamlPage страницу, можно задать ее в качестве новой начальной страницы в файле App.xaml.cs или перейти на новую страницу из MainPage .
Чтобы реализовать навигацию, сначала измените код в конструкторе App.xaml.cs таким образом, чтобы NavigationPage был создан объект :
public App()
В конструкторе MainPage.xaml.cs можно создать простой Button и использовать обработчик событий для перехода по адресу HelloXamlPage :
public MainPage() < InitializeComponent(); Button button = new Button < Text = "Navigate!", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center >; button.Clicked += async (sender, args) => < await Navigation.PushAsync(new HelloXamlPage()); >; Content = button; >
Content Задание свойства страницы заменяет значение Content свойства в XAML-файле. При компиляции и развертывании новой версии этой программы на экране появляется кнопка. При нажатии выполняется переход к HelloXamlPage . Ниже приведена итоговая страница на iPhone, Android и UWP:

Вы можете поэкспериментировать с XAML для различных способов отрисовки Label . Если вам нужно внедрить в текст символы Юникода, можно использовать стандартный синтаксис XML. Например, чтобы поместить приветствие в смарт-кавычки, используйте следующую команду:
Вот как это выглядит:

Xaml и взаимодействие с кодом
Пример HelloXamlPage содержит только один Label элемент на странице, но это очень необычно. Большинство ContentPage производных присваивает Content свойству какой-либо макет, например StackLayout . Свойство Children StackLayout объекта определено как тип IList , но на самом деле это объект типа ElementCollection , и эта коллекция может быть заполнена несколькими представлениями или другими макетами. В XAML эти связи «родители-потомки» устанавливаются с обычной иерархией XML. Ниже приведен файл XAML для новой страницы с именем XamlPlusCodePage:
Этот XAML-файл является синтаксически завершенным, и он выглядит следующим образом:

Однако вы, скорее всего, сочтете эту программу функциональной недостатком. Slider Возможно, предполагается, что объект должен Label отобразить текущее значение, а Button объект , вероятно, предназначен для выполнения действий в программе.
Как вы увидите в части 4. Основные сведения о привязке данных. Задание отображения Slider значения с помощью Label может полностью обрабатываться в XAML с привязкой данных. Но полезно сначала просмотреть решение с кодом. Несмотря на это, для обработки щелчка Button определенно требуется код. Это означает, что файл кода программной части для XamlPlusCodePage должен содержать обработчики для ValueChanged события Slider и Clicked события Button . Давайте добавим их:
namespace XamlSamples < public partial class XamlPlusCodePage < public XamlPlusCodePage() < InitializeComponent(); >void OnSliderValueChanged(object sender, ValueChangedEventArgs args) < >void OnButtonClicked(object sender, EventArgs args) < >> >
Эти обработчики событий не обязательно должны быть открытыми.
В XAML-файле теги и Button должны включать атрибуты для ValueChanged событий и Clicked , Slider которые ссылаются на эти обработчики:
Обратите внимание, что назначение обработчика событию имеет тот же синтаксис, что и назначение значения свойству.
Если обработчик события ValueChanged будет использовать Label для отображения текущего Slider значения, обработчик должен ссылаться на этот объект из кода. Требуется Label имя , которое указывается с помощью атрибута x:Name .
Префикс x атрибута x:Name указывает, что этот атрибут является встроенным в XAML.
Имя, присвоенное атрибуту x:Name , имеет те же правила, что и имена переменных C#. Например, он должен начинаться с буквы или подчеркивания и не содержать внедренных пробелов.
ValueChanged Теперь обработчик событий может задать Label для отображения нового Slider значения. Новое значение доступно в аргументах события:
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
Или обработчик может получить Slider объект, который создает это событие, из аргумента sender и получить Value свойство из этого:
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
При первом запуске программы не отображает Slider значение, Label так как ValueChanged событие еще не сработало. Но любое манипулирование Slider приводит к отображению значения:

Теперь для Button . Давайте смоделируем ответ на Clicked событие, отображая оповещение Text с помощью кнопки . Обработчик событий может безопасно привести аргумент к sender , Button а затем получить доступ к его свойствам:
async void OnButtonClicked(object sender, EventArgs args)
Метод определяется как , так как async DisplayAlert метод является асинхронным и должен быть предваряется оператором await , который возвращается после завершения метода. Так как этот метод получает Button событие срабатывания из аргумента sender , для нескольких кнопок можно использовать один и тот же обработчик.
Вы видели, что объект, определенный в XAML, может вызывать событие, которое обрабатывается в файле кода программной части, и что файл кода программной части может получить доступ к объекту, определенному в XAML, с помощью имени, присвоенного ему атрибутом x:Name . Это два основных способа взаимодействия кода и XAML.
Дополнительные сведения о том, как работает XAML, можно получить, изучив созданный файл XamlPlusCode.xaml.g.cs, который теперь включает любое имя, присвоенное любому x:Name атрибуту в качестве частного поля. Ниже приведена упрощенная версия этого файла:
public partial class XamlPlusCodePage : ContentPage < private Label valueLabel; private void InitializeComponent() < this.LoadFromXaml(typeof(XamlPlusCodePage)); valueLabel = this.FindByName("valueLabel"); > >
Объявление этого поля позволяет свободно использовать переменную в любом месте файла разделяемого XamlPlusCodePage класса в вашей юрисдикции. Во время выполнения поле назначается после анализа XAML. Это означает, что valueLabel поле является null , когда XamlPlusCodePage конструктор начинается, но действителен после InitializeComponent вызова .
После InitializeComponent возврата элемента управления в конструктор визуальные элементы страницы были созданы так же, как если бы они были созданы и инициализированы в коде. XAML-файл больше не играет никакой роли в классе . Вы можете управлять этими объектами на странице любым способом, например добавив представления StackLayout в или задав Content для свойства страницы другое значение. Вы можете «ходить по дереву», изучив Content свойство страницы и элементы в Children коллекциях макетов. Вы можете задать свойства для представлений, к которые осуществляется доступ таким образом, или динамически назначить им обработчики событий.
Не стесняйтесь. Это ваша страница, а XAML — это только инструмент для создания содержимого.
Итоги
В этом вводном руководстве вы узнали, как xaml-файл и файл кода влияют на определение класса, а также как XAML-файлы и файлы кода взаимодействуют. Но XAML также имеет собственные уникальные синтаксические функции, которые позволяют использовать его в очень гибком режиме. Вы можете начать изучение этих возможностей в части 2. Основной синтаксис XAML.
Связанные ссылки
- XamlSamples
- Часть 2. Основной синтаксис XAML
- Часть 3. Расширения разметки XAML
- Часть 4. Основы привязки данных
- Часть 5. Из привязки данных в MVVM