Chat Server and WPF Client
Client
For the client code I used WPF and the MVVM pattern. From the bottom up the first thing I used is a DelegateCommand for the ICommands needed for buttons and what not. This makes the ICommand thing almost easy.
1 using System;
2 using System.Windows.Input;
3
4 namespace ChatClient
5 {
6 class DelegateCommand : ICommand
7 {
8 private readonly Predicate<object> _canExecute;
9 private readonly Action<object> _execute;
10
11 public event EventHandler CanExecuteChanged;
12
13 public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
14 {
15 _execute = execute;
16 _canExecute = canExecute;
17 }
18
19 public bool CanExecute(object parameter)
20 {
21 return _canExecute == null || _canExecute(parameter);
22 }
23
24 public void Execute(object parameter)
25 {
26 _execute(parameter);
27 }
28
29 public void RaiseCanExecuteChanged()
30 {
31 if (CanExecuteChanged != null)
32 {
33 CanExecuteChanged(this, EventArgs.Empty);
34 }
35 }
36 }
37 }
You can see this in the ViewModel used below:
using System.ComponentModel;
using ChatClient.Models;
namespace ChatClient.ViewModels
{
/// <summary>
/// Adaptive code only. You should only see things here that adapt
/// the Model to the view. This is an abstraction of the Model for
/// the express use by the View.
/// </summary>
class ClientViewModel : INotifyPropertyChanged
{
#region Properties
//Elements bound to by the view
public string Message {
get { return _clientModel.CurrentMessage; }
set
{
_clientModel.CurrentMessage = value;
NotifyPropertyChanged("Message");
}
}
public string MessageBoard
{
get { return _clientModel.MessageBoard; }
set
{
_clientModel.MessageBoard = value;
NotifyPropertyChanged("MessageBoard");
}
}
public DelegateCommand ConnectCommand { get; set; }
public DelegateCommand SendCommand { get; set; }
#endregion
#region Private and Internal Vars/Props
private readonly ClientModel _clientModel;
#endregion
/// <summary>
/// Constructor creates the Model!
/// </summary>
public ClientViewModel()
{
//Create ourselves a model
_clientModel = new ClientModel();
//Subscribe to the Model's PropertyChanged event
_clientModel.PropertyChanged += ClientModelChanged;
//Create our two Command objects
ConnectCommand = new DelegateCommand(
a => _clientModel.Connect(),
b => !_clientModel.Connected
);
SendCommand = new DelegateCommand(
a => _clientModel.Send(),
b => _clientModel.Connected
);
}
#region Event Listeners
private void ClientModelChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName.Equals("Connected"))
{
NotifyPropertyChanged("Connected");
ConnectCommand.RaiseCanExecuteChanged();
SendCommand.RaiseCanExecuteChanged();
}
else if (e.PropertyName.Equals("MessageBoard"))
{
NotifyPropertyChanged("MessageBoard");
}
}
#endregion
#region NPC Implementation
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
#endregion NPC Implementation
}
}