我正在尝试开发一个在远程主机上显示 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);
}
}
请注意,异常总是被捕获。
这里的一般问题:如何在集合中找到相同的笔划/点以便相应地删除它们?