Я пытаюсь разработать приложение, которое показывает чертежи WPF InkCanvas на удаленном хосте. В основном он синхронизирует локальный InkCanvas с несколькими удаленными хостами. Я подписался на StrokesChanged
событие:
this.DrawingCanvas.Strokes.StrokesChanged += this.Strokes_StrokesChanged;
И обработчик.
private void Strokes_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e)
{
if (e.Added != null && e.Added.Count > 0)
{
this.StrokeSynchronizer.SendAddedStroke(e.Added);
}
if (e.Removed != null && e.Removed.Count > 0)
{
this.StrokeSynchronizer.SendRemovedStroke(e.Removed);
}
}
Когда я рисую новую кривую, событие вызывается только один раз. Удаленный хост отрисовывает его правильно, вызывая this.RemoteInkCanvas.Strokes.Add(addedStrokes)
.
Когда я стираю кривую с помощью InkCanvasEditingMode.EraseByStroke
, событие также вызывается один раз, и удаленный хост успешно использует this.RemoteInkCanvas.Strokes.Remove(removedStrokes)
.
Вот проблема!
Когда this.DrawingCanvas.EditingMode
равен InkCanvasEditingMode.EraseByPoint
, событие вызывается один раз, но с двумя коллекциями (добавлено и удалено). Это приводит к тому, что удаленные хосты становятся безумными. Вот код удаленного хоста, который стирает штрихи:
private StrokeCollection FindStrokesInLocalCollection(StrokeCollection receivedCollection)
{
var localStrokes = new StrokeCollection();
foreach (var erasedStroke in receivedCollection)
{
var erasedPoints = erasedStroke.StylusPoints;
foreach (var existentStoke in this.RemoteInkCanvas.Strokes)
{
var existentPoints = existentStoke.StylusPoints;
if (erasedPoints.SequenceEqual(existentPoints))
{
localStrokes.Add(existentStoke);
}
}
}
return localStrokes;
}
private void RemoteStrokeRemoved(StrokeCollection strokes)
{
try
{
// Simple this.RemoteInkCanvas.Strokes.Remove(strokes)
// does not work, because local and remote strokes are different (though equal) objects.
// Thus we need to find same strokes in local collection.
var strokesToRemove = this.FindStrokesInLocalCollection(strokes);
if (strokesToRemove.Count != strokes.Count)
{
Logger.Warn(string.Format(
"Whiteboard: Seems like remotely removed strokes were not found in local whiteboard. Remote count {0}, local count {1}.",
strokes.Count,
strokesToRemove.Count));
}
this.RemoteInkCanvas.Strokes.Remove(strokesToRemove);
}
catch (Exception ex)
{
Logger.Error("Whiteboard: Can not remove some strokes received from remote host.", ex);
}
}
Обратите внимание, что исключение всегда ловится.
Общий вопрос здесь: как найти одинаковые штрихи / точки в коллекции, чтобы соответственно их удалить?