Im binding and sending ink strokes as MemoryStream objects using TcpClient, TcpListener but when Im receiving the updated strokes how can I update the UI.
ViewModel : (added INotifyPropertyChanged that fired when we draw something in the View, using Signature_StrokesChanged to send the collection as a MemoryStream)
class MainViewModel : INotifyPropertyChanged
{
public ObservableCollection<UserModel> Users { get; set; }
public ObservableCollection<string> Messages { get; set; }
public RelayCommand ConnectToServerCommand { get; set; }
public RelayCommand SendMessageCommand { get; set; }
public RelayCommand SendInkStrokesCommand { get; set; }
public string UserName { get; set; }
public string Message { get; set; }
private Server _server;
public event PropertyChangedEventHandler PropertyChanged;
public StrokeCollection Signature { get; set; }
public MainViewModel()
{
Users = new ObservableCollection<UserModel>();
Messages = new ObservableCollection<string>();
_server = new Server();
_server.connectedEvent += UserConnected;
_server.msgReceivedEvent += MessageReceived;
_server.inkStrokeReceivedEvent += InkStrokeReceived;
_server.userDisconnectEvent += RemoveUser;
ConnectToServerCommand = new RelayCommand(o => _server.ConnectToServer(UserName), o => !string.IsNullOrEmpty(UserName));
SendMessageCommand = new RelayCommand(o => _server.SendMessageToServer(Message), o => !string.IsNullOrEmpty(Message));
Signature = new StrokeCollection();
Signature.StrokesChanged += Signature_StrokesChanged;
}
public void Signature_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e)
{
Signature = (StrokeCollection)sender;
MemoryStream _ms = new MemoryStream();
Signature.Save(_ms);
_ms.Flush();
_server.SendInkStrokesToServer(_ms);
}
private void InkStrokeReceived()
{
Application.Current.Dispatcher.Invoke(() =>
{
var ink = _server.PacketReader.ReadInkStroke();
MemoryStream memoryStream = new MemoryStream(ink);
Signature = new StrokeCollection(memoryStream);
});
}
private void UserConnected()
{
var user = new UserModel
{
UserName = _server.PacketReader.ReadMessage(),
UID = _server.PacketReader.ReadMessage()
};
if (!Users.Any(x => x.UID == user.UID))
{
Application.Current.Dispatcher.Invoke(() => Users.Add(user));
}
}
private void MessageReceived()
{
var msg = _server.PacketReader.ReadMessage();
Application.Current.Dispatcher.Invoke(() => Messages.Add(msg));
}
private void RemoveUser()
{
var uid = _server.PacketReader.ReadMessage();
var user = Users.Where(u => u.UID == uid).FirstOrDefault();
Application.Current.Dispatcher.Invoke(() => Users.Remove(user));
}
}
Here is my XAML :
<InkCanvas
Name="inkCanv"
Grid.Column="1"
Grid.Row="1"
Height="130"
Background="Azure"
Strokes="{Binding Signature}"
>
</InkCanvas>
Here is how I write them :
public void WriteInkStrokes(byte[] bytesStroke)
{
_ms.Write(BitConverter.GetBytes(bytesStroke.Length));
_ms.Write(bytesStroke);
}
Here is how I read them :
public byte[] ReadInkStroke()
{
byte[] inkBuffer;
var length = ReadInt32();
inkBuffer = new byte[length];
_ns.Read(inkBuffer, 0, length);
return inkBuffer;
}
Here is how I brodacst them :
public static void BrodcastInkStrokes(byte[] inkStrokes)
{
foreach (var user in _users)
{
var inkPacket = new PacketBuilder();
inkPacket.WriteOpCode(7);
inkPacket.WriteInkStrokes(inkStrokes);
user.ClientSocket.Client.Send(inkPacket.GetPacketBytes());
}
}