我正在创建一个Signal R应用程序,在UI上有一个绘图部分,现在我正在使用WPF客户端,但最终还是会有一个MVC和Android客户端。
绘图事件处理得很完美,但是使用我处理删除的方法,其他客户端最终会删除整个笔划而不是仅删除点。
执行擦除的客户端正在使用EraseByPoint方法,一切正常。
绘图更新详细信息通过DrawingDto传递给客户端:
public class DrawingDto
{
public DrawingDto()
{
NewStrokes = new List<StrokeDto>();
DeletedStrokes = new List<StrokeDto>();
}
public IList<StrokeDto> NewStrokes { get; set; }
public IList<StrokeDto> DeletedStrokes { get; set; }
}
public class StrokeDto
{
public StrokeDto()
{
Points = new List<Point>();
}
public IList<Point> Points { get; set; }
}
代码处理器添加新笔划并尝试删除已删除的笔划:
private void OnUpdateDrawing(DrawingDto drawing)
{
Execute.OnUiThread(() =>
{
(Strokes as INotifyCollectionChanged).CollectionChanged -= StrokesOnCollectionChanged;
var strokeCollection = new StrokeCollection();
foreach (var newStroke in drawing.NewStrokes)
{
var pointCollection = new StylusPointCollection();
foreach (var point in newStroke.Points)
{
pointCollection.Add(new StylusPoint(point.X, point.Y));
}
strokeCollection.Add(new Stroke(pointCollection));
}
Strokes.Add(strokeCollection);
foreach (var deletedStroke in drawing.DeletedStrokes)
{
Strokes.Erase(deletedStroke.Points.Select(x=> new System.Windows.Point(x.X, x.Y)), new RectangleStylusShape(1,1));
}
(Strokes as INotifyCollectionChanged).CollectionChanged += StrokesOnCollectionChanged;
});
}
在此代码中,Execute.OnUiThread使用调度程序来调用操作,正在删除事件侦听器以避免向服务器发送递归更新。
最后,代码创建了Dto:
public async void StrokesOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
var dto = new DrawingDto();
if (args.NewItems !=null)
{
foreach (Stroke newStroke in args.NewItems)
{
dto.NewStrokes.Add(new StrokeDto { Points = newStroke.StylusPoints.Select(x => new Point((int)x.X, (int)x.Y)).ToList() });
}
}
if (args.OldItems!= null)
{
foreach (Stroke deletedStroke in args.OldItems)
{
dto.DeletedStrokes.Add(new StrokeDto { Points = deletedStroke.StylusPoints.Select(x => new Point((int)x.X, (int)x.Y)).ToList() });
}
}
await _signalRManager.UpdateDrawing(dto);
}
编辑:这里要求的是信号r代码。
Signal R Hub:
public class DrawingHub : Hub
{
public void UpdateDrawing(DrawingDto drawing)
{
Clients.Others.UpdateDrawing(drawing);
}
}
向Hub发送更新的客户端代码:
public async void StrokesOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
var dto = new DrawingDto();
if (args.NewItems !=null)
{
foreach (Stroke newStroke in args.NewItems)
{
dto.NewStrokes.Add(new StrokeDto { Points = newStroke.StylusPoints.Select(x => new Point((int)x.X, (int)x.Y)).ToList() });
}
}
if (args.OldItems!= null)
{
foreach (Stroke deletedStroke in args.OldItems)
{
dto.DeletedStrokes.Add(new StrokeDto { Points = deletedStroke.StylusPoints.Select(x => new Point((int)x.X, (int)x.Y)).ToList() });
}
}
await _signalRManager.UpdateDrawing(dto);
}
来自SignalRManager的Snippet(这是一个包含所有代理的单例类):
public async Task UpdateDrawing(DrawingDto dto)
{
await DrawingProxy.Invoke("UpdateDrawing", dto);
}
public event Action<DrawingDto> UpdateDrawingEvent;
private void OnUpdateDrawing(DrawingDto drawing)
{
if(UpdateDrawingEvent != null) UpdateDrawingEvent.Invoke(drawing);
}
答案 0 :(得分:1)
好的,这里的问题是对InkCanvas如何处理擦除的误解。
在StrokesOnCollectionChanged
处理程序中,OldItems集合将包含橡皮擦触及的任何笔划的全部内容,而NewItems将包含在橡皮擦击中原始内容时分割的新笔划。
因为在OnUpdateDrawing
代码中首先处理新项目然后删除旧项目,我实际上正在删除刚刚添加的新笔画。
现在通过处理删除的笔划,首先一切都按预期工作,代码片段:
private void OnUpdateDrawing(DrawingDto drawing)
{
Execute.OnUiThread(() =>
{
(Strokes as INotifyCollectionChanged).CollectionChanged -= StrokesOnCollectionChanged;
var strokeCollection = new StrokeCollection();
foreach (var deletedStroke in drawing.DeletedStrokes)
{
Strokes.Erase(deletedStroke.Points.Select(x => new System.Windows.Point(x.X, x.Y)), new RectangleStylusShape(0.01, 0.01));
}
foreach (var newStroke in drawing.NewStrokes)
{
var pointCollection = new StylusPointCollection();
foreach (var point in newStroke.Points)
{
pointCollection.Add(new StylusPoint(point.X, point.Y));
}
strokeCollection.Add(new Stroke(pointCollection));
}
Strokes.Add(strokeCollection);
(Strokes as INotifyCollectionChanged).CollectionChanged += StrokesOnCollectionChanged;
});
}
答案 1 :(得分:0)
我不明白,你为什么不这样做:
foreach (var deletedStroke in drawing.DeletedStrokes)
Strokes.Remove(deletedStroke);