- •1. Вводная часть
- •2. Знакомство со средой разработки на примере создания простого консольного приложения
- •3. Модификация консольного приложения
- •4. Публикация
- •5. О приложении к Лабораторной работе № 1
- •Лабораторная работа № 2: Создание простого приложения Windows Forms
- •Создание простого приложения Windows Forms
- •Модификация приложения Windows Forms
- •Завершающая часть
- •2. Создание простого приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Завершающая часть
- •5. О приложении к Лабораторной работе № 2
- •3. Лабораторная работа № 3: Windows Forms и использование некоторых элементов управления Лабораторная работа № 3: Windows Forms и использование некоторых элементов управления
- •Вводная часть
- •О приложении к Лабораторной работе № 3
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Модификация приложения Windows Forms: элемент управления MenuStrip
- •5. Модификация приложения Windows Forms: элемент управления Button
- •6. Модификация приложения Windows Forms: элемент управления ToolTip
- •7. Модификация приложения Windows Forms: элемент управления ComboBox
- •8. Модификация приложения Windows Forms: элемент управления WebBrowser
- •9. Модификация приложения Windows Forms: добавляем исходный код
- •10. Завершающая часть
- •11. О приложение к Лабораторной работе № 3
- •4. Лабораторная работа № 4: Windows Forms — работа с формами Лабораторная работа № 4: Windows Forms — работа с формами
- •Вводная часть
- •О приложении к Лабораторной работе № 4
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Модификация приложения Windows Forms: добавление новой формы
- •5. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через прямой доступ к элементу формы
- •6. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через передачу метода в конструктор формы
- •7. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через класс делегата
- •8. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через свойства
- •9. Завершающая часть
- •10. О приложении к Лабораторной работе № 4
- •5. Лабораторная работа № 5: Windows Forms — элементы управления Лабораторная работа № 5: Windows Forms — элементы управления
- •Вводная часть
- •О приложении к Лабораторной работе № 5
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Модификация приложения Windows Forms: динамическое добавление и уничтожение элемента управления
- •5. Модификация приложения Windows Forms: стандартные диалоговые окна
- •6. Модификация приложения Windows Forms: открытие файла, сохранение файла и работа с текстом
- •7. Модификация приложения Windows Forms: прочее
- •8. Завершающая часть
- •9. О приложении к Лабораторной работе № 5
- •Лабораторная работа № 6: SolidWorks — работа с SolidWorks
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: eDrawings 2012
- •4. Модификация приложения Windows Forms: организация работы с SolidWorks через приложение
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 6
- •Лабораторная работа № 7: SolidWorks — использование SwCSharpAddin, работа с макросом и шаблоном детали
- •2. Создание приложения SwCSharpAddin
- •3. Модификация приложения SwCSharpAddin: макрос отрисовки болта
- •4. Модификация приложения SwCSharpAddin: построение через шаблон детали
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 7
- •8. Лабораторная работа № 8: Создание простого приложения Windows Foundation Presentation Лабораторная работа № 8: Создание простого приложения Windows Foundation Presentation
- •Вводная часть
- •О приложении к Лабораторной работе № 8
- •1. Вводная часть
- •2. Создание приложения Windows Foundation Presentation
- •3. Модификация приложения Windows Foundation Presentation
- •4. Модификация приложения Windows Foundation Presentation: добавление нового элемента из библиотеки компонентов wpf
- •5. Модификация приложения Windows Forms: расширение функциональности приложения и работа с оформление
- •6. Модификация приложения Windows Foundation Presentation: различные возможности wpf
- •7. Модификация приложения Windows Foundation Presentation: немного о стилях и шаблонах
- •8. Завершающая часть
- •9. О приложении к Лабораторной работе № 8
- •Лабораторная работа № 9: Создание приложения-презентации Windows Foundation Presentation
- •2. Создание приложения Windows Foundation Presentation
- •3. Модификация приложения Windows Foundation Presentation
- •4. Модификация приложения Windows Foundation Presentation: работа с решением в Expression Blend
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 9
- •Лабораторная работа № 10: Работа с базами данных — xml и ole
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: odbc
- •4. Модификация приложения Windows Forms: ole
- •5. Модификация приложения Windows Forms: xml
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 10
- •Лабораторная работа № 11: Динамическая связь приложений через библиотеку классов
- •2. Удалённый объект: создание библиотеки классов удалённого объекта
- •3. Клиент: создание приложения Windows Forms
- •4. Сервер: создание консольного приложения
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 11
- •Лабораторная работа № 12: Автоматизация Microsoft Office Word
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: создание и заполнение нового документа Microsoft Word
- •4. Модификация приложения Windows Forms: работа с шаблонами
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 12
- •Лабораторная работа № 13: Автоматизация Microsoft Office Excel
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: создание и заполнение нового документа Microsoft Excel
- •4. Модификация приложения Windows Forms: чтение данных с документа Microsoft Excel
- •5. Модификация приложения Windows Forms: прочие возможности Microsoft Excel
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 13
- •Лабораторная работа № 14: Простой растровый редактор
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: подготовка интерфейса редактора
- •4. Модификация приложения Windows Forms: функциональность растрового редактора
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 14
- •15. Лабораторная работа № 15: Векторный редактор изображений Лабораторная работа № 15: Векторный редактор изображений
- •Вводная часть
- •О приложении к Лабораторной работе № 15
- •1. Вводная часть
- •2. Создание решения, приложения Windows Forms и библиотеки классов
- •3. Модификация приложения Windows Forms: подготовка интерфейса редактора и добавление файлов ресурсов
- •4. О будущей функциональности векторного редактора изображений
- •5. Модификация приложения Windows Forms: подготовка библиотеки классов
- •6. Модификация приложения Windows Forms: функциональность векторного редактора
- •7. Завершающая часть
- •8. О приложении к Лабораторной работе № 15
- •Лабораторная работа № 16: Windows Communication Foundation
- •2. Создание приложения wcf:
- •3. Модификация приложения wcf: приложение-клиент для wcf-службы
- •4. Создание приложения Windows Forms: сервер чата на wcf
- •5. Создание приложения Windows Forms: клиент чата на wcf
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 16
- •Лабораторная работа № 17: Знакомство с Silverlight
- •2. Создание приложения Silverlight:
- •3. Модификация приложения Silverlight: первые шаги и полноэкранный режим
- •4. Модификация приложения Silverlight: простой проигрыватель mp3-файлов
- •5. Модификация приложения Silverlight: работа с анимацией
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 17
- •Лабораторная работа № 18: Знакомство с asp.Net
- •2. Создание веб-приложения asp.Net
- •3. Модификация веб-приложения asp.Net: реализация различной функциональности
- •4. Модификация веб-приложения asp.Net: ajax
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 18
- •Вводная часть
- •О приложении к Лабораторной работе № 19
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: подготовка интерфейса и добавление TabControl
- •4. Модификация приложения Windows Forms: вкладка «Просто фон!»
- •5. Модификация приложения Windows Forms: вкладка «Объекты и градиент»
- •6. Модификация приложения Windows Forms: вкладка «Мой монитор сломался!»
- •7. Модификация приложения Windows Forms: вкладка «Векторные часы»
- •8. Модификация приложения Windows Forms: вкладка «Огонь!!!»
- •9. Модификация приложения Windows Forms: вкладка «Дождик»
- •10. Завершающая часть
- •11. О приложении к Лабораторной работе № 19
- •Лабораторная работа № 20: Inventor — работа с Inventor
- •Вводная часть
- •О приложении к Лабораторной работе № 20
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: запуск и завершение приложения Inventor
- •4. Модификация приложения Windows Forms: создание новых документов
- •5. Модификация приложения Windows Forms: доступ к элементам документов Inventor
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 20
- •Лабораторная работа № 21: Знакомство с языком f# (Эф-шарп) на примере простого приложения для командной строки
- •Вводная часть
- •О приложении к Лабораторной работе № 21
- •1. Вводная часть
- •2. Основные положения при работе с f#
- •3. Создание приложения «Учебник по f#»
- •4. Создание консольного приложения
- •5. О приложении к Лабораторной работе № 21
- •Лабораторная работа № 22: Различные примеры на f#
- •2. Создание приложения «Приложение f#»
- •3. Модификация приложения f#: match
- •4. Модификация приложения f#: создание форм и рисование объектов на форме
- •5. Модификация приложения f#: работа с базой данных Microsoft Access
- •6. О приложении к Лабораторной работе № 22
- •23. Дополнительная лабораторная работа № 1
- •24. Дополнительная лабораторная работа № 2
- •25. Дополнительная лабораторная работа № 3
- •Вводная часть
- •1. Вводная часть
- •2. Создание приложения Windows Foundation Presentation
- •3. Модификация приложения Windows Foundation Presentation: добавление ресурсов
- •4. Модификация приложения Windows Foundation Presentation: добавление исходного кода
- •5. Модификация приложения Windows Foundation Presentation: оформление элемента ListBox
- •6. Завершающая часть
- •7. О приложении к данной работе
5. Создание приложения Windows Forms: клиент чата на wcf
Для создания клиентского приложения выполним аналогичные пункту № 4 данной лабораторной работы действия.
Создаём новый проект в текущем решении (LWP16). Для этого выполним следующие действия: Файл -> Создать -> Проект. В окне открывшемся окне «Создать проект», в поле Решение, выберем: Добавить в решение. В качестве проекта выберем Приложение Windows Forms. Имя будет: LWP16-ChatClient. Жмём ОК.
Сразу же добавим необходимые библиотеки. Должен быть выбрать текущий проект в обозревателе решений (LWP16-ChatClient). Выполним Проект -> Добавить ссылку... -> в окне Добавить ссылку переходим на вкладку .NET и ищем System.ServiceModel. Если ОС на которой запущена среда разработки Windows 7, добавим также ещё одну библиотеку: Microsoft Speech Object Library (вкладка COM):
Рис. 5. 2. Добавить ссылку: добавляем новую ссылку на библиотеку Microsoft Speech Object Library
Переименуем форму проекта клиентского приложений в обозревателе решений (ПКМ на иконке формы -> Переименовать). Новое имя формы будет LWP16MainClient. После переименования, автоматически изменится свойство (Name) формы.
Теперь изменим свойства формы LWP16MainClient:
Text |
изменим с Form1 на Чат на WCF (C#) :: Клиент |
^ Поменяем заголовок формы (то, что отображается в шапке приложения слева).
MaximizeBox |
изменим с True на False |
^ Уберём кнопку Развернуть.
Icon |
изменим изображение (иконку) приложения |
^ Необходим файл значка *.ico.
FormBorderStyle |
> изменим с Sizable на FixedDialog |
^ Сделаем окно «неизменяем» по размерам.
Size |
изменим со значений 290; 290 на 300; 125 |
^ Поменяем размер формы.
Расставим элементы с панели инструментов как показано на рисунке ниже:
Рис. 5. 1. Расстановка элементов на форме приложения-клиента
Здесь у нас в первой группе (GroupBox) «Пользовательские данные»: один Label, один TextBox и Button.
Свойства элементов следующие:
GroupBox:
(Name): |
GB_UserDetails |
Text: |
Пользовательские данные |
Label:
(Name): |
L_LoginInfo |
Text: |
Введите имя для входа и нажмите на «Войти в чат» |
TextBox:
(Name): |
TB_UserName |
Button:
(Name): |
B_Login |
Text: |
Войти в чат |
Во второй группе элементов один GroupBox и один ListBox:
GroupBox:
(Name): |
GB_UserList |
Text: |
Пользователи в сети |
ListBox:
(Name): |
LB_Users |
Последняя группа содержит один RichTextBox, TextBox и две кнопки.
GroupBox:
(Name): |
GB_MessageWindow |
Text: |
Сообщения чата |
RichTextBox:
(Name): |
RTB_Messages |
ReadOnly: |
True |
Multiline |
True |
TextBox:
(Name): |
TB_SendMessage |
Button:
(Name): |
B_Send |
Text: |
Отправить |
Button:
(Name): |
B_WakeUp |
Text: |
! |
Перейдём к редактированию кода формы. В начале файла с кодом для формы LWP16MainClient.cs объявим:
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Runtime.InteropServices;
using SpeechLib; // Для работы имитации голоса (в Windows XP не использовать)
Найдём:
namespace LWP16_ChatClient
{
Добавим после:
[ServiceContract(CallbackContract = typeof(ILWP16Service))]
public interface ILWP16Service // Интерфейс подключения к службе сервера
{
[OperationContract(IsOneWay = true)] // Операция не возвращает ответовное сообщение
void Join(string memberName); // Объявление метода присоединения к чату (по имени)
[OperationContract(IsOneWay = true)]
void SendMessage(string memberName, string message); // Объявление метода отсылки сообщения (по имени и тексту)
[OperationContract(IsOneWay = true)]
void WakeUp(string memberName, string wakeup); // Объявление метода отсылки сообщения (по имени и тексту)
[OperationContract(IsOneWay = true)]
void Leave(string memberName); // Объявление метода выхода из чата (по имени)
[OperationContract(IsOneWay = true)]
void ImageFF(string memberName, Bitmap image); // Объявление метода выхода из чата (по имени)
}
public interface ILWP16Channel : ILWP16Service, IClientChannel
{
}
Найдём:
public partial class LWP16MainClient : Form
{
Заменим на:
public partial class LWP16MainClient : Form, ILWP16Service
{
[DllImport("kernel32.dll")]
public static extern bool Beep(int BeepFreq, int BeepDuration);
private delegate void UserJoined(string name);
private delegate void UserSendMessage(string name, string message);
private delegate void UserWakeUp(string name, string wakeup);
private delegate void UserLeft(string name);
private static event UserJoined NewJoin; // Экземпляр события присоединения к чату через делегат
private static event UserSendMessage MessageSent; // Экземпляр события отсылки сообщения через делегат
private static event UserWakeUp NewWakeUp; // Экземпляр события сообщения типа: "разбудить чат"
private static event UserLeft RemoveUser; // Экземпляр события выхода из чата через делегат
private string userName; // Переменная имени пользователя в чате
private ILWP16Channel channel; // Экземпляр интерфейса чата для канала
// class ServiceModel.DuplexChannelFactory<TChannel>
private DuplexChannelFactory<ILWP16Channel> factory; // Объект средства приёма и передаче "дуплексных" сообщений по каналам в обе стороны
Метод LWP16MainClient() измени так:
public LWP16MainClient()
{
InitializeComponent();
this.AcceptButton = B_Login; // Привязываем событие Нажатия Enter с кнопкой "Войти в чат"
}
После добавим:
public LWP16MainClient(string userName)
{
this.userName = userName;
}
// Метод присоединения к чату (по имени)
void LWP16Client_NewJoin(string name)
{
RTB_Messages.AppendText("\r\n");
RTB_Messages.AppendText(name + " присоединился: [" + DateTime.Now.ToString() + "]"); // Добавляем в RichTextBox строчку c именем и датой входа пользователя
LB_Users.Items.Add(name); // Добавляем нового пользователя в ListBox
}
// Метод отсылки сообщения (по имени и тексту)
void LWP16Client_MessageSent(string name, string message)
{
if (!LB_Users.Items.Contains(name)) // Если имени нет в ListBox при получении сообщения в RichTextBox
{
LB_Users.Items.Add(name); // Добавляет нового пользователя в ListBox
}
RTB_Messages.AppendText("\r\n");
RTB_Messages.AppendText(name + " говорит: " + message + " [" + DateTime.Now.ToString() + "]"); // Добавляем в RichTextBox строчку с именем и сообщением
if (message == "WakeUp") { Beep(500, 100); }
}
// Метод присоединения к чату (по имени)
void LWP16Client_WakeUp(string name, string wakeup)
{
if (!LB_Users.Items.Contains(name)) // Если имени нет в ListBox при получении сообщения в RichTextBox
{
LB_Users.Items.Add(name); // Добавляет нового пользователя в ListBox
}
RTB_Messages.AppendText("\r\n");
RTB_Messages.AppendText(name + " попытался разбудить чат: [" + DateTime.Now.ToString() + "]"); // Добавляем в RichTextBox строчку c именем и датой входа пользователя
if (wakeup == "WakeUp")
{
Beep(500, 100);
Beep(500, 100);
SpVoice voice = new SpVoice();
voice.Speak("Wake Up Mate", SpeechVoiceSpeakFlags.SVSFDefault);
}
}
// Метод выхода из чата (по имени)
void LWP16Client_RemoveUser(string name)
{
try
{
RTB_Messages.AppendText("\r\n");
RTB_Messages.AppendText(name + " вышел: [" + DateTime.Now.ToString() + "]"); // Добавляем в RichTextbox строчку с именем и датой выхода пользователя
LB_Users.Items.Remove(name); // Удаляем по имени из ListBox
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.ToString());
}
}
void Online(object sender, EventArgs e)
{
RTB_Messages.AppendText("\r\nВ сети: " + this.userName);
}
void Offline(object sender, EventArgs e)
{
RTB_Messages.AppendText("\r\nНе в сети: " + this.userName);
}
#region ILWP16Service Основные методы
public void Join(string memberName)
{
if (NewJoin != null)
{
NewJoin(memberName);
}
}
public void SendMessage(string memberName, string message)
{
if (MessageSent != null)
{
MessageSent(memberName, message);
}
}
public void WakeUp(string memberName, string wakeup)
{
if (NewWakeUp != null)
{
NewWakeUp(memberName, wakeup);
}
}
public new void Leave(string memberName)
{
if (RemoveUser != null)
{
RemoveUser(memberName);
}
}
#endregion
Перейдём к событиям формы. Для кнопки «Войти в чат» событие Click будет содержать код:
private void B_Login_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(TB_UserName.Text.Trim()))
{
try
{
NewJoin += new UserJoined(LWP16Client_NewJoin); // Переопределяем вызов метода подключения к чату через экзмепляр события
MessageSent += new UserSendMessage(LWP16Client_MessageSent); // Переопределяем вызов метода отсылки сообщения в чат через экзмепляр события
NewWakeUp += new UserWakeUp(LWP16Client_WakeUp); // Переопределяем вызов метода "разбудить чат" в чат через экзмепляр события
RemoveUser += new UserLeft(LWP16Client_RemoveUser); // Переопределяем вызов метода выхода из чата через экзмепляр события
channel = null;
this.userName = TB_UserName.Text.Trim(); // Удаляем пробелы из имени пользователя
// class ServiceModel.InstanceContext
InstanceContext context = new InstanceContext(new LWP16MainClient(TB_UserName.Text.Trim()));
factory = new DuplexChannelFactory<ILWP16Channel>(context, "ChatEndPoint"); // Получаем данные из app.config и передаём данные duplex-каналу
channel = factory.CreateChannel(); // Создаём канал и передаём его экземпляру интерфейса чата
// class ServiceModel.IOnlineStatus
IOnlineStatus status = channel.GetProperty<IOnlineStatus>(); // Определяем экземпляр для индикации доступности объекта по каналу
status.Offline += new EventHandler(Offline); // Вызов метода Offline (если в чате больше никого)
status.Online += new EventHandler(Online); // Вызов метода Online (если в чате больше одного пользователя)
channel.Open(); // Открываем канал
channel.Join(this.userName); // Вызываем метод Join() с текущим именем пользователя введённым в TB_Username
GB_MessageWindow.Enabled = true; // Включаем группу "Сообщения чата"
GB_UserList.Enabled = true; // Включаем группу "Список пользователей"
GB_UserDetails.Enabled = false; // Гасим группу "Данные для входа"
this.AcceptButton = B_Send; // Enter = "Отослать"
RTB_Messages.AppendText("*****************************ДОБРО ПОЖАЛОВАТЬ В ЧАТ*****************************\r\n");
TB_SendMessage.Select();
TB_SendMessage.Focus();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
События Click кнопок «Отправить» и «!»:
private void B_Send_Click(object sender, EventArgs e)
{
channel.SendMessage(this.userName, TB_SendMessage.Text.Trim()); // Вызываем метод SendMessage() и отсылаем имя пользователя и сообщение
TB_SendMessage.Clear(); // Очищаем TB_SendMessage и далее передаём фокус на элемент и делаем его активным
TB_SendMessage.Select();
TB_SendMessage.Focus();
}
private void B_WakeUp_Click(object sender, EventArgs e)
{
channel.WakeUp(this.userName, "WakeUp"); // Вызываем метод WakeUp() и отсылаем имя пользователя и текст "WakeUp"
TB_SendMessage.Clear(); // Очищаем TB_SendMessage и далее передаём фокус на элемент и делаем его активным
TB_SendMessage.Select();
TB_SendMessage.Focus();
}
Событие FormClosing формы LWP16MainClient:
private void LWP16MainClient_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
if (channel != null)
{
channel.Leave(this.userName); // Если закрываем форму, вызваем метод Leave() и удаляем пользователя
channel.Close(); // Закрываем канал между сервером и клиентом
}
if (factory != null)
{
factory.Close(); // Закрываем duplex-канал
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Теперь разъясним принцип работы всего того что было тут наворочено. После запуска приложения-сервера, происходит инициализация канала по определённому адресу. Был выбран локальный адрес и порт 5433, а также абсолютное имя пространства имён LWP16_ChatServer для адресации по этому порту. Имя для адресации в строке конфигурации клиента:
<endpoint name="ChatEndPoint" address="net.p2p://LWP16-Сhat/LWP16_ChatServer"
И...
<custom address="net.tcp://localhost:5433/LWP16_ChatServer"
Может быть любым, но! Главное чтобы оно совпадало с серверной строкой адреса (в файле конфигурации приложения-сервера). То есть, запущенное приложение-клиент должно содержать в файле конфигурации этот абсолютный адрес.
После ввода имени, становится доступной кнопка «Войти в чат». После нажатия на кнопку, в приложении-клиенте происходит вызов (через делегат и событие) метода интерфейса: Join(string memberName), содержащее переданное из текстового поля строку с именем. И далее выполняется: LWP16Client_NewJoin(string name), где в RichTextBox добавляется запись о присоединении пользователя с таким-то именем к чату и временем присоединения. Имя также добавляется в ListBox. Если пользователь в уже не один, срабатывает метод Online(), которые сразу же оповещает и пользователя и другого пользователя о том, что они «в сети». Метод срабатывает в том случае, если в сети больше одного пользователя, после нажатия кнопки «Войти в чат» пользователя ещё не вошедшего в чат. Вызывает событие после получения по каналу «индикатора события доступности»:
IOnlineStatus status = channel.GetProperty<IOnlineStatus>();
Подключение третьего пользователя не вызывает срабатывание метода у двух предыдущих, но «в сети» отображается у нового пользователя, которому выдаётся оповещение о том что в канале он не один. Также любое подключение вызывает у всех клиентов срабатывание события NewJoin и следовательно Join(<имя подключившегося>).
Сообщение отсылается по такому же событийному механизму, но содержит также текст сообщения, которое пользователь набрал у себя в клиенте. Отправка идёт после нажатия кнопки «Отправить». В ListBox новый пользователи чата добавляются лишь по факту совершения события и появления записи с именем в RichTextBox, потом если в сети один клиент, то об имени уже находящегося в канале пользователя новый клиент узнает только после совершения тем пользователем действий.
Аналогичным образом работает событие WakeUp, которое передаёт чату имя пользователя нажавшего кнопку «!» и текст «WakeUp», который не отображается в чате. После получения такого сообщения, все клиенты издают системный звук (чтобы разбудить тех кто находится в чате). А также, если ОС на которой запущен клиент это Windows Vista или Windows 7, то приложение проговаривает заранее заготовленную фразу. Также системный звук раздаётся, если написать в чат непосредственно слово WakeUp.
Выход из чата (через закрытие формы и вызов события FormClosing) тоже выдаёт оповещения, а также происходит удаление имени вышедшего из ListBox всех клиентов.
Наше приложение-клиент готово. Можно компилировать и проверять работоспособность.