如何实现一个能显示几何信息且完全自适应的调试窗口?
我有一个处理几何的项目,虽然可以逐步查看代码并看到数值,但若不查看正在使用/生成的几何体,要核对所有内容相当困难。
我能否在Visual Studio中拥有一个名为“几何调试”的窗口,在调试主程序时完全响应,并且能够在调试过程中添加几何体?
我正在尝试做一个WPF窗口,在调试期间(例如通过即时窗口打开)可以打开,并对点击和滚动完全响应,同时还能接受向该窗口添加几何体的调用。
到目前为止,据说如果在新线程中创建并显示该窗口,就能让它完全响应,但事实并非如此。窗口看起来没有响应,只有在主程序(正在调试的那个)单步跳过几行后才会继续。
这是窗口绑定的(不完全等同于)视图模型的代码:
internal class WpfDebugGeometryVM
{
... some properties to bind ...
//a geometry collection bound to the window
private ObservableCollection<DebugGeometry> _ChartObjects;
public ReadOnlyObservableCollection<DebugGeometry> ChartObjects { get; private set; }
//the window dispatcher for asynchronous calls
private Dispatcher WindowDispatcher;
//main method to show the window in another thread, called from immediate
//returns the viewmodel to be able to add geometry from the Immediate
public static WpfDebugGeometryVM? ShowDebugWindow()
{
WpfDebugGeometryVM? viewModel = null;
ManualResetEvent threadStarted = new ManualResetEvent(false);
Thread thread = new Thread(() =>
{
SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));
WpfDebugGeometry window = new WpfDebugGeometry();
WpfDebugGeometryVM localViewModel = new WpfDebugGeometryVM(window);
window.SetDataContext(localViewModel);
viewModel = localViewModel;
threadStarted.Set();
window.Show();
Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
threadStarted.WaitOne();
//the idea is to use this to add geometry from the Immedite Window
return viewModel;
}
//viewmodel constructor, called only in the other thread
private WpfDebugGeometryVM(WpfDebugGeometry window)
{
WindowDispatcher = window.Dispatcher;
_ChartObjects = new ObservableCollection<DebugGeometry>();
ChartObjects = new ReadOnlyObservableCollection<DebugGeometry>(_ChartObjects);
ChartExtents = new BoundingBox2d(0, 0, 1, 1);
SetGeometryExtents();
}
#region adding geometry
//adds geometry using the Dispatcher
public void AddPoint(Point2dGeom point, double radius, Brush color, bool updateZoom)
{
WindowDispatcher.BeginInvoke(() =>
{
AddPoint(point, radius, color);
if (updateZoom) ResetZoom();
});
}
....
}
我想做的这件事可能吗?我是否可以拥有这样一个完全响应的窗口,并从即时窗口向其中添加几何体?(现在我需要在调试中再往前走几步才会让窗口出现,而且它并不真正响应。)
此外,即使在Thread方法内部设置了断点也永远不会命中(尽管窗口在某个时刻确实会显示)
解决方案
可以通过 自定义数据可视化工具来扩展Visual Studio。这应该可以让你在调试时显示一个窗口并可视化你的几何对象。由于我自己没尝试过,无法提供更多信息,但文档看起来相当详细。
我所做的是在主应用中创建一个特殊的“调试”设置标志,用来启用各种可视化。具体实现会有所不同,但通常包括显示几何体的变换或边界框等。设计系统时让添加对任意几何体的可视化以用于调试特定问题变得很简单,并在之后再移除,这一点也非常有用。
虽然我通常不推荐使用单例模式,但这确实是一个例外,优点可能超过缺点。使用一个静态方法会非常方便,比如 DebugVisualizer.ShowSphere(myPosition, myRadius, "myName", Colors.HotPink) 这样的,你可以把它放在任何地方。你也可以使用“热重载”(Hot Reload)在运行时插入这样的调用。
另外,提供一个在覆盖层中显示坐标值的选项也会非常有用,这样你就可以实时看到数值,而无需中断调试器。
在我看来,在处理三维几何时,花相当多的时间设计一个良好的调试可视化系统是值得的,因为这会让解决各种问题变得更加容易。