我正在创建一个在 UI 上具有绘图部分的 Signal R 应用程序,现在我正在使用 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 集线器:
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 的片段(这是一个包含所有代理的单例类):
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);
}