При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан. Затем: Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз. |
Финальный проект — программа education center
Форма frmDirection — форма указания направления
Эта форма используется для создания новых учебных направлений в окне проводника главной формы. Для добавления направления щелкаем в проводнике правой кнопкой и в появившемся контекстном меню выбираем New-Direction (рис. 11.31).
В результате появляется окно, в которое вводим название направления и его описание (рис. 11.32).
Приступим к созданию этой формы. Помещаем на нее из окна ToolBox следующие элементы управления:
- Элемент TextBox txtDirectionName, две надписи Label lblDirectionName и lblDirectionNote со свойствами Text "Направление:" и "Описание:" соответственно. Элемент TextBox txtDirectionNote (устанавливаем свойству MultiLine значение true ). Для элементов TextBox создаем обработчики событий Validated (см. код программы).
- Добавляем на форму две кнопки btnOK и btnCancel со свойствами Text "OK" и "Cancel" соответственно. Для них создаем обработчиков события Click (см. код программы). Также устанавливаем свойства DialogResult для этих кнопок "OK" и "Cancel" соответственно.
Устанавливаем свойства формы frmDirection:
Для формы создаем обработчик события Load (см. код программы).
В классе формы добавляем поле и свойство для него:
private DataRow bindingRow; internal DataRow BindingRow { get { return bindingRow; } set { bindingRow = value; } }
Помимо конструктора по умолчанию, будем использовать следующий конструктор:
public frmDirection(DataRow bindingRow) { InitializeComponent(); this.bindingRow = bindingRow; this.txtDirectionName.Text = bindingRow["directName"].ToString(); this.txtDirectionNote.Text = bindingRow["note"].ToString(); }
Далее листинг формы:
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 frmDirection : System.Windows.Forms.Form { // Описание элементов управления public frmDirection() { InitializeComponent(); } private DataRow bindingRow; internal DataRow BindingRow { get { return bindingRow; } set { bindingRow = value; } } public frmDirection(DataRow bindingRow) { InitializeComponent(); this.bindingRow = bindingRow; this.txtDirectionName.Text = bindingRow["directName"].ToString(); this.txtDirectionNote.Text = bindingRow["note"].ToString(); } protected override void Dispose( bool disposing ) { // Описание метода } private void InitializeComponent() { // Описание метода } #endregion private void txtDirectionName_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) if (txtDirectionName.Text != this.bindingRow["directName"].ToString()) { this.bindingRow["directName"] = txtDirectionName.Text; } } private void txtDirectionNote_Validated(object sender, System.EventArgs e) { if (this.bindingRow != null) if (txtDirectionNote.Text != this.bindingRow["note"].ToString()) { this.bindingRow["note"] = txtDirectionNote.Text; } } private void frmDirection_Load(object sender, System.EventArgs e) { txtDirectionName.Focus(); } } }Листинг 11.4.
Форма frmClientTransfer — форма перевода клиента
При копировании клиента из группы и последующей его вставки в другую группу появляется промежуточная форма перевода. Для ее создания помещаем на форму из окна ToolBox следующие элементы управления (рис. 11.33):
Листинг этой формы:
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace Manager { /// <summary> /// Промежуточная форма управления клиентом. /// </summary> public class frmClientTransfer : System.Windows.Forms.Form { // Описание элементов управлений public frmClientTransfer() { InitializeComponent(); } protected override void Dispose( bool disposing ) { // Описание метода } private void InitializeComponent() { // Описание метода } private void frmClientTransfer_Load(object sender, System.EventArgs e) { txtClientName.Focus(); } } }Листинг 11.5.
Форма frmSearchClient — форма для поиска клиентов
В программе реализована возможность поиска клиентов по фамилии, имени или дате записи. Располагаем на форме элементы управления, изображенные на рис. 11.34.
Для кнопок создаем обработчиков события Click. (см. код программы). Обратите внимание, что в коде вместо конструктора по умолчанию используется другой конструктор с параметром. Класс формы также был наследован от интерфейса ISelectingForm, и были переопределены его члены.
Листинг формы frmSearchClient:
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Data.SqlClient; using System.Text; using SelectingFormInterface; using Manager.Forms; namespace Manager { /// <summary> /// Форма для поиска клиентов /// </summary> public class frmSearchClient : System.Windows.Forms.Form, ISelectingForm { private DataTable dtClients; // Таблица клиентов public DataView dvSearchRez; private CurrencyManager currManagerClients; public CurrencyManager CurrencyManagerClients { get { return currManagerClients; } set { currManagerClients = value; } } // Объявление элементов управления public frmSearchClient(MainDataSet mainDataSet) { InitializeComponent(); this.mainDataSet = mainDataSet; this.MakeStyleForDataGrid(); dtClients = mainDataSet.clients; dtClients.RowChanged += new DataRowChangeEventHandler(dtSearchRez_RowChanged); dgSearchRez.MouseUp += new MouseEventHandler(dgSearchRez_MouseUp); dgSearchRez.Click += new EventHandler(dgSearchRez_Click); currManagerClients = (CurrencyManager)this.BindingContext[mainDataSet, "income"]; } private void MakeStyleForDataGrid() { DataGridTableStyle clientsTableStyle = new DataGridTableStyle(); clientsTableStyle.MappingName = "clients"; DataGridTextBoxColumn clientIDStyle = new DataGridTextBoxColumn(); clientIDStyle.MappingName = "clientID"; clientIDStyle.Width = 50; clientIDStyle.HeaderText = "ID"; DataGridTextBoxColumn clientFirstNameStyle = new DataGridTextBoxColumn(); clientFirstNameStyle.MappingName = "fname"; clientFirstNameStyle.Width = 150; clientFirstNameStyle.HeaderText = "Имя"; DataGridTextBoxColumn clientLastNameStyle = new DataGridTextBoxColumn(); clientLastNameStyle.MappingName = "lname"; clientLastNameStyle.Width = 150; clientLastNameStyle.HeaderText = "Фамилия"; DataGridTextBoxColumn clientFatherNameStyle = new DataGridTextBoxColumn(); clientFatherNameStyle.MappingName = "fathName"; clientFatherNameStyle.Width = 150; clientFatherNameStyle.HeaderText = "Отчество"; DataGridTextBoxColumn clientLinkDataStyle = new DataGridTextBoxColumn(); clientLinkDataStyle.MappingName = "linkData"; clientLinkDataStyle.Width = 150; clientLinkDataStyle.HeaderText = "Контакты"; DataGridTextBoxColumn clientRecordDateStyle = new DataGridTextBoxColumn(); clientRecordDateStyle.MappingName = "recorddate"; clientRecordDateStyle.Width = 150; clientRecordDateStyle.HeaderText = "Дата записи"; DataGridTextBoxColumn clientNotesStyle = new DataGridTextBoxColumn(); clientNotesStyle.MappingName = "note"; clientNotesStyle.Width = 150; clientNotesStyle.HeaderText = "Заметки"; DataGridTextBoxColumn clientPaymentTypeStyle = new DataGridTextBoxColumn(); clientPaymentTypeStyle.MappingName = "paymentType"; clientPaymentTypeStyle.Width = 150; clientPaymentTypeStyle.HeaderText = "Вид оплаты"; clientsTableStyle.GridColumnStyles.AddRange(new DataGridColumnStyle[] { clientIDStyle, clientFirstNameStyle, clientLastNameStyle, clientFatherNameStyle, clientLinkDataStyle, clientRecordDateStyle, clientNotesStyle, clientPaymentTypeStyle}); dgSearchRez.TableStyles.Add(clientsTableStyle); } protected override void Dispose( bool disposing ) { // Описание метода } private void InitializeComponent() { // Описание метода } // Начать поиск private void btnFind_Click(object sender, System.EventArgs e) { try { dvSearchRez = new DataView(dtClients); string str = @"fname LIKE '" + txtFname.Text + @"' OR lname LIKE '" + txtLname.Text + @"'" + @" OR recorddate = '" + dtpRecDate.Value.Date.ToString() + @"'"; dvSearchRez.RowFilter = str; dgSearchRez.DataSource = dvSearchRez; currManagerClients = (CurrencyManager)this.BindingContext[dvSearchRez, null]; } catch (Exception ex) { MessageBox.Show(ex.Message, ex.Source); } } // Обновление данных private void btnGetChanges_Click(object sender, System.EventArgs e) // внести изменения { try { daSearch.Update(dtClients.GetChanges()); btnGetChanges.Enabled = false; } catch(Exception ex) { MessageBox.Show(ex.Message, ex.Source); } } // Доступ к кнопке изменений private void dtSearchRez_RowChanged(object sender, DataRowChangeEventArgs e) { btnGetChanges.Enabled = true; } private void btnExit_Click(object sender, System.EventArgs e) { this.Close(); } private void dgSearchRez_ShowParentDetailsButtonClick(object sender, EventArgs e) { MessageBox.Show("OK"); } private void dgSearchRez_MouseUp(object sender, MouseEventArgs e) { Point point = new Point(e.X, e.Y); int rowIndex = dgSearchRez.CurrentRowIndex; if (rowIndex >= 0) { System.Windows.Forms.DataGrid.HitTestInfo hti = dgSearchRez.HitTest(point); this.SelectedRow = dvSearchRez[hti.Row].Row; } } #region IFindingForm Members private DataRow selectedRow; public DataRow SelectedRow { get { return selectedRow; } set { selectedRow = value; } } #endregion } }Листинг 11.6.