-1

リモートホストでWPFInkCanvasの描画を表示するアプリケーションを開発しようとしています。基本的に、ローカル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);
        }
    }

新しい曲線を描画しているとき、イベントは1回だけ呼び出されます。リモートホストは、を呼び出すことによってそれを正しく描画しthis.RemoteInkCanvas.Strokes.Add(addedStrokes)ます。

イベントを介してカーブを消去しているときInkCanvasEditingMode.EraseByStrokeも一度呼び出され、リモートホストはthis.RemoteInkCanvas.Strokes.Remove(removedStrokes)正常に使用します。

ここに問題があります!

this.DrawingCanvas.EditingModeの場合、InkCanvasEditingMode.EraseByPointイベントは1回呼び出されますが、2つのコレクション(追加と削除)があります。これにより、リモートホストが異常になります。ストロークを消去するリモートホストコードは次のとおりです。

    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を使用してマークアップの3行を削除すると、まさに必要なものになります。

StrokesCollectionをCodeBehind/VMに含める場合は、それを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 に答える