-1

我正在尝试开发一个在远程主机上显示 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);
        }
    }

请注意,异常总是被捕获。

这里的一般问题:如何在集合中找到相同的笔划/点以便相应地删除它们?

4

2 回答 2

1

我不确定您是否需要让它变得如此复杂,但这是一个仅 WPF 标记的解决方案,它应该完全满足您的需求:

http://msdn.microsoft.com/en-us/library/system.windows.controls.inkcanvas.aspx

请参阅 API 定义后的示例。如果您使用 LayoutTransform 删除标记中的三行,它应该正是您所需要的。

如果您想在 CodeBehind/VM 中使用 StrokesCollection,请将其绑定为 DependencyProperty 或 VM 属性,然后您就可以设置了。

于 2011-12-21T08:58:26.680 回答
0

问题在于 StrokesCollection 使用的序列化/反序列化机制。当一个double值被序列化和反序列化时,结果值会略有不同。

完整的代码示例和答案可以在这里找到:http ://social.msdn.microsoft.com/Forums/en-AU/wpf/thread/9e1f43fa-6266-41b7-a5d0-7603f87ca58f

于 2012-01-04T11:10:05.137 回答