При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан. Затем: Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз. |
Финальный проект — программа education center
Форма frmCourse — форма курсов
При выборе одного из направлений в проводнике можно добавлять новые курсы, щелкнув правой кнопкой и выбрав в контекстном меню пункт New/Сourse (рис. 11.39):
Располагаем элементы управления и называем их в соответствии с рис. 11.40.
Листинг формы frmCourse:
using System; using System.Data; using System.Data.SqlClient; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace Manager { /// <summary> /// Форма курса /// </summary> public class frmCourse : System.Windows.Forms.Form { // Объявление элементов управления public frmCourse() { InitializeComponent(); } private DataRow bindingRow; internal DataRow BindingRow { get { return bindingRow; } set { bindingRow = value; } } public frmCourse(DataRow bindingRow) { InitializeComponent(); this.bindingRow = bindingRow; this.lblCourseNumber.Text += bindingRow.ItemArray[0].ToString(); this.txtCourseName.Text = bindingRow.ItemArray[1].ToString(); this.txtCoursePrice.Text = bindingRow.ItemArray[4].ToString(); } protected override void Dispose( bool disposing ) { // Описание метода } private void InitializeComponent() { // Описание метода } private void txtCourseName_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) if (txtCourseName.Text != this.bindingRow["courseName"].ToString()) { this.bindingRow["courseName"] = txtCourseName.Text; } } private void txtCoursePrice_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) if (double.Parse(txtCourseName.Text) != (double)this.bindingRow["priceNumber"]) { this.bindingRow["priceNumber"] = double.Parse(txtCourseName.Text); } } private void frmCourse_Load(object sender, System.EventArgs e) { txtCourseName.Focus(); } } }Листинг 11.8.
Форма frmEmployee
В программе предусмотрена возможность извлечения, добавления и изменения информации о сотрудниках центра. Для этого используется форма frmEmployee, добавляем элементы управления в соответствии с рис. 11.41.
Класс формы frmEmployee наследуем от интерфейса ISelectingForm.
Листинг формы frmEmployee:
using System; using System.Data; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using SelectingFormInterface; using Manager.Forms; namespace Manager { public class frmEmployee : System.Windows.Forms.Form, ISelectingForm { // Объявление элементов управления #region IFindingForm Members private DataRow selectedRow = null; public DataRow SelectedRow { get { return selectedRow; } set { selectedRow = value; } } #endregion public frmEmployee(MainDataSet mainDataSet) { InitializeComponent(); this.mainDataSet = mainDataSet; this.InitDefaultSettings(); } protected override void Dispose( bool disposing ) { // Описание метода } private void InitializeComponent() { // Описание метода } private void InitDefaultSettings() { try { cmEmployees = (CurrencyManager)this.BindingContext[mainDataSet, "employees"]; txtEmployeeFirstName.DataBindings.Add("Text", mainDataSet, "employees.FirstName"); txtEmployeeLastName.DataBindings.Add("Text", mainDataSet, "employees.LastName"); txtEmployeeFatherName.DataBindings.Add("Text", mainDataSet, "employees.FatherName"); dtpBirthday.DataBindings.Add("Value", mainDataSet, "employees.birthDay"); txtEmployeeNotes.DataBindings.Add("Text", mainDataSet, "employees.linkData"); cmbDirections.DataBindings.Add("Text", mainDataSet, "employees.directionID"); dgEmployees.DataSource = mainDataSet.employees; dgEmployees.MouseUp += new MouseEventHandler(dgEmployees_MouseUp); btnNext.Click += new EventHandler(btnNext_Click); btnPrev.Click += new EventHandler(btnPrev_Click); this.DesignDatagrid(); } catch (Exception ex) { MessageBox.Show(ex.Message, ex.Source); } } private void miExit_Click(object sender, System.EventArgs e) { this.Close(); } private void btnNext_Click(object sender, EventArgs e) { if (cmEmployees.Position < mainDataSet.employees.Rows.Count) cmEmployees.Position++; } private void btnPrev_Click(object sender, EventArgs e) { if (cmEmployees.Position > 0) cmEmployees.Position--; } private void SetSelectedRow(DataGrid dataGrid, DataGrid.HitTestInfo hti) { try { int rowIndex = hti.Row; DataTable table = (DataTable)dataGrid.DataSource; if (rowIndex == table.Rows.Count) return; DataRow selectedRow = table.Rows[rowIndex]; this.SelectedRow = selectedRow; } catch (Exception ex) { MessageBox.Show(ex.Message, ex.Source); } } private void dgEmployees_MouseUp(object sender, MouseEventArgs e) { DataGrid.HitTestInfo hti = dgEmployees.HitTest(e.X, e.Y); if ((hti.Row != -1) && (hti.Column != -1)) SetSelectedRow(dgEmployees, hti); } private void DesignDatagrid() { DataGridTableStyle employeesTableStyle = new DataGridTableStyle(); employeesTableStyle.MappingName = "employees"; DataGridTextBoxColumn employeeIDStyle = new DataGridTextBoxColumn(); employeeIDStyle.MappingName = "employeeID"; employeeIDStyle.Width = 50; employeeIDStyle.HeaderText = "ID"; DataGridTextBoxColumn lastNameStyle = new DataGridTextBoxColumn(); lastNameStyle.MappingName = "LastName"; lastNameStyle.Width = 120; lastNameStyle.HeaderText = "Фамилия"; DataGridTextBoxColumn firstNameStyle = new DataGridTextBoxColumn(); firstNameStyle.MappingName = "FirstName"; firstNameStyle.Width = 150; firstNameStyle.HeaderText = "Имя"; DataGridTextBoxColumn fatherNameStyle = new DataGridTextBoxColumn(); fatherNameStyle.MappingName = "amountToday"; fatherNameStyle.Width = 150; fatherNameStyle.HeaderText = "Отчество"; DataGridTextBoxColumn linkDataStyle = new DataGridTextBoxColumn(); linkDataStyle.MappingName = "linkData"; linkDataStyle.Width = 150; linkDataStyle.HeaderText = "Контакты"; DataGridTextBoxColumn birthDayStyle = new DataGridTextBoxColumn(); birthDayStyle.MappingName = "birthDay"; birthDayStyle.Width = 100; birthDayStyle.HeaderText = "День рождения"; DataGridTextBoxColumn directionIDStyle = new DataGridTextBoxColumn(); directionIDStyle.MappingName = "directionID"; directionIDStyle.Width = 60; directionIDStyle.HeaderText = "directionID"; DataGridTextBoxColumn addressStyle = new DataGridTextBoxColumn(); addressStyle.MappingName = "Address"; addressStyle.Width = 300; addressStyle.HeaderText = "Адрес"; DataGridTextBoxColumn notesStyle = new DataGridTextBoxColumn(); notesStyle.MappingName = "Notes"; notesStyle.Width = 100; notesStyle.HeaderText = "Notes"; DataGridTextBoxColumn passportSerialNumberStyle = new DataGridTextBoxColumn(); passportSerialNumberStyle.MappingName = "PassportSerialNumber"; passportSerialNumberStyle.Width = 100; passportSerialNumberStyle.HeaderText = "Серия паспорта"; DataGridTextBoxColumn dataPrinyatiyaStyle = new DataGridTextBoxColumn(); dataPrinyatiyaStyle.MappingName = "DataP"; dataPrinyatiyaStyle.Width = 100; dataPrinyatiyaStyle.HeaderText = "DataP"; DataGridTextBoxColumn kStyle = new DataGridTextBoxColumn(); kStyle.MappingName = "K"; kStyle.Width = 100; kStyle.HeaderText = "K"; DataGridTextBoxColumn postStyle = new DataGridTextBoxColumn(); postStyle.MappingName = "Post"; postStyle.Width = 100; postStyle.HeaderText = "Post"; employeesTableStyle.GridColumnStyles.AddRange(new DataGridTextBoxColumn[] { employeeIDStyle, lastNameStyle, firstNameStyle, fatherNameStyle, linkDataStyle, birthDayStyle, directionIDStyle, addressStyle, notesStyle, passportSerialNumberStyle, dataPrinyatiyaStyle, kStyle, postStyle}); dgEmployees.TableStyles.Add(employeesTableStyle); } } }Листинг 11.9.
Форма frmGroup — форма добавления новой группы
Для добавления группы по выбранному курсу используется форма frmGroup. Добавляем элементы управления в соответствии с рис. 11.42.
Листинг формы frmGroup:
using System; using System.Drawing; using System.Data; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using Manager.Forms; namespace Manager { /// <summary> /// Форма группы /// </summary> public class frmGroup : System.Windows.Forms.Form { // Объявление элементов управления internal CurrencyManager cmEmployees; internal CurrencyManager cmGroupStatus; private Manager.Forms.MainDataSet mainDataSet; private DataRow bindingRow; internal DataRow BindingRow { get { return bindingRow; } set { bindingRow = value; } } public frmGroup(MainDataSet mainDataSet) { InitializeComponent(); this.mainDataSet = mainDataSet; cmbStatus.DataSource = mainDataSet.GroupStatus; cmbStatus.DisplayMember = "StatusName"; cmGroupStatus = (CurrencyManager)this.BindingContext[mainDataSet, "GroupStatus"]; cmGroupStatus.Position = 0; cmbEmployee.DataSource = mainDataSet.employees; cmbEmployee.DisplayMember = "EmployeeName"; cmEmployees = (CurrencyManager)this.BindingContext[mainDataSet, "employees"]; cmEmployees.Position = 0; Size labelSize = new Size(this.Width, lblGroupID.Size.Height); this.lblGroupID.Size = labelSize; } public frmGroup(MainDataSet ds, DataRow bindingRow) { InitializeComponent(); mainDataSet = ds; cmbStatus.DataSource = mainDataSet.GroupStatus; cmbStatus.DisplayMember = "StatusName"; cmGroupStatus = (CurrencyManager)this.BindingContext[mainDataSet, "GroupStatus"]; DataView dvStatus = (DataView)cmGroupStatus.List; dvStatus.Sort = "StatusID"; int statusPos = dvStatus.Find(bindingRow["StatusID"]); cmbStatus.SelectedIndex = statusPos; cmbEmployee.DataSource = mainDataSet.employees; cmbEmployee.DisplayMember = "EmployeeName"; cmEmployees = (CurrencyManager)this.BindingContext[mainDataSet, "employees"]; DataView dvEmployee = (DataView)cmEmployees.List; dvEmployee.Sort = "employeeID"; int employeePos = dvEmployee.Find(bindingRow["employeeID"]); cmbEmployee.SelectedIndex = employeePos; Size labelSize = new Size(this.Width, lblGroupID.Size.Height); this.lblGroupID.Size = labelSize; this.bindingRow = bindingRow; int groupID = (int)bindingRow[0]; this.lblGroupID.Text += groupID.ToString(); DateTime beginDate = (DateTime)bindingRow[1]; this.dtpBeginDate.Value = beginDate; DateTime endDate = (DateTime)bindingRow[2]; this.dtpEndDate.Value = endDate; if (bindingRow.ItemArray[3] == null) { this.dtpBeginTime.Text = ""; } else { DateTime beginTime = (DateTime)bindingRow[3]; this.dtpBeginTime.Text = beginTime.ToString("HH:mm"); } if (bindingRow.ItemArray[4] == null) { this.dtpEndTime.Text = ""; } else { DateTime endTime = (DateTime)bindingRow[4]; this.dtpEndTime.Text = endTime.ToString("HH:mm"); } this.txtNotes.Text = bindingRow[9].ToString(); this.cmbClassNumber.Text = bindingRow[6].ToString(); } protected override void Dispose( bool disposing ) { // Описание метода } private void InitializeComponent() { // Описание метода } private void frmGroup_Load(object sender, System.EventArgs e) { txtNotes.Focus(); } // Проверка обновлений в элементах управлений private void dtpBeginDate_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) if (dtpBeginDate.Value != (DateTime)this.bindingRow["beginDate"]) { this.bindingRow["beginDate"] = DateTime.Parse(dtpBeginDate.Value.ToString("dd MMMM yyyy")); } } private void dtpEndDate_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) if (dtpEndDate.Value != (DateTime)this.bindingRow["endDate"]) { this.bindingRow["endDate"] = DateTime.Parse(dtpEndDate.Value.ToString("dd MMMM yyyy")); } } private void dtpBeginTime_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) if (dtpBeginTime.Value != (DateTime)this.bindingRow["beginTime"]) { this.bindingRow["beginTime"] = DateTime.Parse(dtpBeginTime.Value.ToString("HH:mm")); } } private void dtpEndTime_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) if (dtpEndTime.Value != (DateTime)this.bindingRow["endTime"]) { this.bindingRow["endTime"] = DateTime.Parse(dtpEndTime.Value.ToString("HH:mm")); } } private void txtNotes_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) if (txtNotes.Text != this.bindingRow["note"].ToString()) { this.bindingRow["note"] = txtNotes.Text; } } private void cmbClassNumber_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) if (cmbClassNumber.Text != this.bindingRow["classNumber"].ToString()) { this.bindingRow["classNumber"] = cmbClassNumber.Text; } } private void cmbStatus_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) { DataRow statusRow = this.bindingRow.GetParentRow("GroupStatusgroups"); if (cmbStatus.Text != statusRow["StatusName"].ToString()) { this.bindingRow["StatusID"] = cmbStatus.SelectedIndex + 1; } } } } }Листинг 11.10.
Форма frmPaymentType — форма для произведения оплаты за услуги
На вкладке "Оплаты" при нажатии на одноименную кнопку появляется окно, в котором можно указывать вид расчетов. Добавляем элементы управления в соответствии с рис. 11.43.
Класс формы должен наследовать от интерфейса ISelectingForm.
Листинг формы frmPaymentType:
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using SelectingFormInterface; using System.Data; using Manager.Forms; namespace Manager { public class frmPaymentType : System.Windows.Forms.Form, ISelectingForm { private MainDataSet mainDataSet = null; public frmPaymentType(MainDataSet mainDataSet) { InitializeComponent(); this.mainDataSet = mainDataSet; this.InitialDefaultSettings(); } protected override void Dispose( bool disposing ) { //Описание метода } private void InitializeComponent() { //Описание метода } private System.Windows.Forms.DataGrid dgPaymentType; private System.Windows.Forms.Button btnOK; private System.Windows.Forms.Button bntCancel; private DataRow selectedRow = null; public DataRow SelectedRow { get { return selectedRow; } set { selectedRow = value; } } private void InitialDefaultSettings() { dgPaymentType.DataSource = mainDataSet; dgPaymentType.DataMember = "payment_type"; dgPaymentType.Click += new EventHandler(dgPaymentType_Click); dgPaymentType.CurrentCellChanged += new EventHandler(dgPaymentType_CurrentCellChanged); this.DesignDataGrid(); } private void DesignDataGrid() { // Дизайн таблицы payment_type DataGridTableStyle paymentTypeStyle = new DataGridTableStyle(); paymentTypeStyle.MappingName = "payment_type"; DataGridTextBoxColumn paymentTypeIDStyle = new DataGridTextBoxColumn(); paymentTypeIDStyle.MappingName = "payment_typeID"; paymentTypeIDStyle.Width = 50; paymentTypeIDStyle.HeaderText = "ID"; DataGridTextBoxColumn paymentTypeNameStyle = new DataGridTextBoxColumn(); paymentTypeNameStyle.MappingName = "payment_typeName"; paymentTypeNameStyle.Width = 100; paymentTypeNameStyle.HeaderText = "Name"; DataGridTextBoxColumn paymentTypeNoteStyle = new DataGridTextBoxColumn(); paymentTypeNoteStyle.MappingName = "note"; paymentTypeNoteStyle.Width = 200; paymentTypeNoteStyle.HeaderText = "Notes"; paymentTypeStyle.GridColumnStyles.AddRange( new DataGridTextBoxColumn[] { paymentTypeIDStyle, paymentTypeNameStyle, paymentTypeNoteStyle}); dgPaymentType.TableStyles.Add(paymentTypeStyle); } private void dgPaymentType_Click(object sender, EventArgs e) { if ((dgPaymentType.CurrentCell.RowNumber != -1) && (dgPaymentType.CurrentCell.ColumnNumber != -1)) dgPaymentType_CurrentCellChanged(dgPaymentType, new EventArgs()); } private void dgPaymentType_CurrentCellChanged(object sender, EventArgs e) { try { this.SelectedRow = mainDataSet.payment_type.Rows[dgPaymentType.CurrentRowIndex]; } catch (Exception ex) { MessageBox.Show(ex.Message, ex.Source); } } } }Листинг 11.11.
Дополнительные классы
В проекте были использованы дополнительные классы, листинг которых приводится далее.
Класс ManagerTreeNode(ManagerTreeNode.cs)
using System; using System.Windows.Forms; using System.Data; using System.Data.SqlClient; namespace Manager { internal abstract class ManagerTreeNode : TreeNode { internal abstract void GetChilds(); } }Листинг 11.12.
Класс ClientTreeNode(Clients.cs)
using System; using System.Windows.Forms; namespace Manager { internal class ClientTreeNode : ManagerTreeNode { internal ClientTreeNode() { } private int clientID; internal int ClientID { get { return clientID; } set { clientID = value; } } private int groupID; internal int GroupID { get { return groupID; } set { groupID = value; } } private int courseID; internal int CourseID { get { return courseID; } set { courseID = value; } } private string firstName; internal string FirstName { get { return firstName; } set { firstName = value; } } private string lastName; internal string LastName { get { return lastName; } set { lastName = value; } } private string fatherName; internal string FatherName { get { return fatherName; } set { fatherName = value; } } private string linkData; internal string LinkData { get { return linkData; } set { linkData = value; } } private DateTime recorddate; internal DateTime RecordDate { get { return recorddate; } set { recorddate = value; } } private string note; internal string Note { get { return note; } set { note = value; } } private string paymentType; internal string PaymentType { get { return paymentType; } set { paymentType = value; } } private double clientSumm; internal double ClientSumm { get { return clientSumm; } set { clientSumm = value; } } internal override void GetChilds() { } public override string ToString() { return lastName + " " + firstName + " " + fatherName; } } }Листинг 11.13.
Класс GroupTreeNode (Groups.cs)
using System; using System.Collections; using System.Windows.Forms; using System.Data; using System.Data.SqlClient; using System.Drawing; using Manager.Forms; namespace Manager { internal class GroupTreeNode : ManagerTreeNode { private MainDataSet mainDataSet = null; internal MainDataSet NDDataSet { get { return mainDataSet; } set { mainDataSet = value; } } private int courseID; internal int CourseID { get { return courseID; } set { courseID = value; } } private int groupID; internal int GroupID { get { return groupID; } set { groupID = value; } } private DateTime beginDate; internal DateTime BeginDate { get { return beginDate; } set { beginDate = value; } } private DateTime endDate; internal DateTime EndDate { get { return endDate; } set { endDate = value; } } private DateTime beginTime; internal DateTime BeginTime { get { return beginTime; } set { beginTime = value; } } private DateTime endTime; internal DateTime EndTime { get { return endTime; } set { endTime = value; } } private int clientsCount; internal int ClientsCount { get { return clientsCount; } set { clientsCount = value; } } private int classNumber; internal int ClassNumber { get { return classNumber; } set { classNumber = value; } } private int directionID; internal int DirectionID { get { return directionID; } set { directionID = value; } } private int employeeID; internal int EmployeeID { get { return employeeID; } set { employeeID = value; } } private string groupNote; internal string GroupNote { get { return groupNote; } set { groupNote = value; } } private int status; internal int Status { get { return status; } set { status = value; } } internal override void GetChilds() { DataView dvGroupClients = new DataView(this.NDDataSet.group_clients); dvGroupClients.RowFilter = "groupID = " + this.GroupID.ToString(); ClientTreeNode[] ctns = new ClientTreeNode[dvGroupClients.Count]; ClientTreeNode ctn = null; int i = 0; foreach(DataRowView drv in dvGroupClients) { DataRow clientRow = drv.Row.GetParentRow("clientsgroup_clients"); ctn = new ClientTreeNode(); ctn.ClientID = (int)clientRow["clientID"]; ctn.FirstName = clientRow["fname"].ToString(); ctn.LastName = clientRow["lname"].ToString(); ctn.FatherName = clientRow["fathName"].ToString(); ctn.LinkData = clientRow["linkData"].ToString(); ctn.RecordDate = (DateTime)clientRow["recordDate"]; ctn.Note = clientRow["note"].ToString(); ctn.PaymentType = clientRow["paymentType"].ToString(); ctn.Text = ctn.LastName + " " + ctn.FirstName + " " + ctn.FatherName; ctn.ImageIndex = 6; ctn.ForeColor = Color.Teal; ctn.Tag = clientRow; ctns[i++] = ctn; ctn = null; } this.ForeColor = Color.Crimson; this.Nodes.AddRange(ctns); } } }Листинг 11.14.
Класс CourseTreeNode (Courses.cs)
using System; using System.Collections; using System.Windows.Forms; using System.Data; using System.Data.SqlClient; using System.Drawing; using Manager.Forms; namespace Manager { internal class CourseTreeNode : ManagerTreeNode { private MainDataSet mainDataSet = null; internal MainDataSet NDDataSet { get { return mainDataSet; } set { mainDataSet = value; } } private int directionID; internal int DirectionID { get { return directionID; } set { directionID = value; } } private int courseID; internal int CourseID { get { return courseID; } set { courseID = value; } } private string courseName; internal string CourseName { get {return courseName;} set {courseName = value;} } private decimal coursePrice; internal decimal CoursePrice { get { return coursePrice; } set { coursePrice = value; } } public override string ToString() { return courseName; } internal override void GetChilds() { DataView dvGroups = new DataView(this.NDDataSet.groups); dvGroups.RowFilter = "courseID = " + this.courseID.ToString(); GroupTreeNode[] gtns = new GroupTreeNode[dvGroups.Count]; GroupTreeNode gtn = null; int i = 0; foreach (DataRowView drv in dvGroups) { DataRow dr = drv.Row; gtn = new GroupTreeNode(); gtn.NDDataSet = this.NDDataSet; gtn.CourseID = this.courseID; gtn.GroupID = (int)dr["groupID"]; gtn.BeginDate = (DateTime)dr["beginDate"]; gtn.EndDate = (DateTime)dr["endDate"]; gtn.BeginTime = (DateTime)dr["beginTime"]; gtn.EndTime = (DateTime)dr["endTime"]; gtn.ClientsCount = (int)dr["clientsCount"]; gtn.ClassNumber = (int)dr["classNumber"]; gtn.CourseID = (int)dr["courseID"]; gtn.EmployeeID = (int)dr["employeeID"]; gtn.GroupNote = dr["note"].ToString(); gtn.Status = (int)dr["statusID"]; gtn.Text = gtn.GroupID.ToString(); gtn.ImageIndex = 6; if ((int)dr["StatusID"] == 1) // Группа набирается { gtn.ForeColor = Color.Red; } else if ((int)dr["StatusID"] == 2) // Группа обучается { gtn.ForeColor = Color.Green; } else if ((int)dr["StatusID"] == 3) // Группа закончила обучение { gtn.ForeColor = Color.Blue; } gtn.Tag = dr; gtns[i++] = gtn; gtn = null; } this.ForeColor = Color.Green; this.Nodes.AddRange(gtns); } } }Листинг 11.15.
Класс DirectionTreeNode(Directions.cs)
using System; using System.Collections; using System.Windows.Forms; using System.Data; using System.Data.SqlClient; using System.Drawing; using Manager.Forms; namespace Manager { internal class DirectionTreeNode : ManagerTreeNode { private MainDataSet mainDataSet = null; internal MainDataSet NDDataSet { get { return mainDataSet; } set { mainDataSet = value; } } private string directionName; internal string DirectionName { get { return directionName; } set { directionName = value; } } private string managerFirstName; internal string ManagerFirstName { get { return managerFirstName; } set { managerFirstName = value; } } private string managerLastName; internal string ManagerLastName { get { return managerLastName; } set { managerLastName = value; } } private string managerFatherName; internal string ManagerFatherName { get { return managerFatherName; } set { managerFatherName = value; } } private int directionID; internal int DirectionID { get { return directionID; } set { directionID = value; } } private string directionNote; internal string DirectionNote { get { return directionNote; } set { directionNote = value; } } private int managerID; internal int ManagerID { get { return managerID;} set { managerID = value;} } public override string ToString() { return directionName; } internal override void GetChilds() { DataView dvCourse = new DataView(this.NDDataSet.course); dvCourse.RowFilter = "directionID = " + this.directionID.ToString(); CourseTreeNode[] ctns = new CourseTreeNode[dvCourse.Count]; CourseTreeNode ctn = null; int i = 0; foreach (DataRowView drv in dvCourse) { DataRow dr = drv.Row; ctn = new CourseTreeNode(); ctn.NDDataSet = this.NDDataSet; ctn.DirectionID = this.directionID; ctn.CourseID = int.Parse(dr["courseID"].ToString()); ctn.CourseName = ctn.Text = dr["courseName"].ToString(); ctn.CoursePrice = (decimal)dr["priceNumber"]; ctn.ImageIndex = 10; ctn.ForeColor = Color.Green; ctn.GetChilds(); ctn.Tag = dr; // Теперь мы можем обращаться к элементам в ListView по свойству tag ctns[i++] = ctn; ctn = null; } this.ForeColor = Color.RoyalBlue; this.Nodes.AddRange(ctns); } } }Листинг 11.16.
Класс CustomListItem(CustomListItem.cs)
using System; using System.Data; namespace Manager { // Класс содержит строку для данного объекта из БД public class CustomListItem : System.Windows.Forms.ListViewItem { public CustomListItem():base() { bindedRow = null; } public CustomListItem(string[] subItems, int imageIndex):base(subItems, imageIndex) { bindedRow = null; } private DataRow bindedRow; internal DataRow BindedRow { get { return bindedRow; } set { bindedRow = value; } } } }Листинг 11.17.
Интерфейс ISelectingForm(SelectingFormInterface.cs)
Этот интерфейс наследуют формы, в которых можно выбирать какие-нибудь записи:
using System; using System.Data; using System.Windows.Forms; namespace SelectingFormInterface { public interface ISelectingForm { DataRow SelectedRow { get; set; } } }Листинг 11.18.
Элемент управления FindControl (FindControl.cs)
Добавляем в окне Solution Explorer новый проект Windows Control Library и называем его FindControl. Это пользовательский элемент управления, с которыми мы сталкивались в "Работа с элементами управления (продолжение)" .
Добавляем на форму три кнопки в соответствии с рис. 11.44.
Листинг формы FindControl:
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using System.Reflection; using SelectingFormInterface; namespace FindControl { public delegate void RowSelectedDelegate(FindControl findControl, DataTable table); public class FindControl : System.Windows.Forms.UserControl { /// <summary> /// Событие генерируется, когда выбрана запись из формы поиска в режиме диалога /// </summary> public event RowSelectedDelegate RowSelected; private ISelectingForm selectingForm = null; public ISelectingForm SelectingForm { get { return selectingForm; } set { selectingForm = value; } } private Form personForm = null; public Form PersonForm { get { return personForm; } set { personForm = value; } } private string text = ""; public override string Text { get { return text; } set { text = value; btnFind.Text = text; } } private DataRow targetRow = null; /// <summary> /// Запись, в которую добавляется значение из формы поиска и выбора /// </summary> public DataRow TargetRow { get { return targetRow; } set { targetRow = value; } } private string columnName = null; private System.Windows.Forms.Button btnData; /// <summary> /// Название колонки, в которую можно добавить номер выбранной записи из формы поиска и выбора /// </summary> public string ColumnName { get { return columnName; } set { columnName = value; } } private DataTable table = null; /// <summary> /// Таблица, в которую добавляется запись /// </summary> public DataTable Table { get { return table; } set { table = value; } } public FindControl() { InitializeComponent(); this.btnCancel.Click += new EventHandler(btnCancel_Click); this.btnFind.Click += new EventHandler(btnFind_Click); this.btnData.Click += new EventHandler(btnData_Click); } protected override void Dispose( bool disposing ) { if( disposing ) { if( components != null ) components.Dispose(); } base.Dispose( disposing ); } #region Component Designer generated code private void InitializeComponent() { // Описание метода } #endregion private void btnCancel_Click(object sender, EventArgs e) { this.Visible = true; this.Dispose(); } private void btnFind_Click(object sender, EventArgs e) { try { Form form = (Form)this.SelectingForm; if (form.ShowDialog() == DialogResult.OK) RowSelected(this, this.Table); btnCancel_Click(btnCancel, new EventArgs()); } catch (Exception ex) { MessageBox.Show(ex.Message, ex.Source); } } public override string ToString() { return "FindControl"; } private void btnData_Click(object sender, EventArgs e) { if (personForm == null) { MessageBox.Show("Нет данных для отображения формы"); return; } personForm.ShowDialog(); this.Dispose(); } } }Листинг 11.19.
На диске, прилагаемом к книге, вы найдете приложение EducationCenter (Code\Glava11\ Manager).