在winforms中处理丢失的graphics设备XNA 4.0

我正在尝试在我的关卡编辑器中添加一个新function。 部分function是当用户在地图上放置一个新的贴图时popup一个窗体,但是一旦窗体出现,XNAembedded式屏幕就会抛出一个大的红色X.我认为这是由于embedded式屏幕失去焦点到forms然后崩溃。

这是表单初始化的地方

public Form1() { InitializeComponent(); //Node Editor tileDisplay1.OnInitialize += new EventHandler(tileDisplay1_OnInitialize); tileDisplay1.OnDraw += new EventHandler(tileDisplay1_OnDraw); Microsoft.Xna.Framework.Input.Keys[] allKeys = (Microsoft.Xna.Framework.Input.Keys[]) Enum.GetValues(typeof(Microsoft.Xna.Framework.Input.Keys)); foreach (var key in allKeys) KeyboardInput.AddKey(key); KeyboardInput.KeyRelease += new KeyHandler(KeyboardInput_KeyRelease); MouseInput.MouseMove += new MouseMoveHandler(MouseInput_MouseMove); MouseInput.MouseDown += new MouseClickHandler(MouseInput_MouseDown); MouseInput.MouseUp += new MouseClickHandler(MouseInput_MouseUp); Application.Idle += delegate { tileDisplay1.Invalidate(); }; saveFileDialog1.Filter = "Map File|*.map"; Mouse.WindowHandle = tileDisplay1.Handle; } 

这是平局事件发生的地方

 void tileDisplay1_OnDraw(object sender, EventArgs e) { Logic(); Render(); KeyboardInput.Update(); MouseInput.Update(); foreach (var actor in Actor.Actors) actor.Update(); } 

这是表单被调用的地方

  private void Logic() { if (colIndex == 8 && AssociateBox.SelectedIndex == 0) { currentCollisionLayer.SetCellIndex(collideCellX, collideCellY,form.spawnNumber.ToString()); if(form.spawnNumber == "12") { camdetails.ShowDialog(); } } } 

当绘制/更新代码抛出exception时,WinForms示例中的“Big Red X”出现。 而不是简单地忽略它,WinForms示例捕获exception,切换到显示Big Red X,并停止调用绘图/更新代码。

这相当于一个正常的XNA程序退出时出现“未处理的exception”错误。

简单地重置graphics设备并尝试继续是错误的解决scheme。

你需要做的是找出抛出exception的地方,并停止它渗透过你的绘图/更新代码。 尝试在Visual Studio中设置“打破例外”。 或者将你的绘图/更新代码包装在try-catch块中并添加一个断点。

我建议阅读位于以下位置的WinForms上的XNA AppHub示例: http ://create.msdn.com/en-US/education/catalog/sample/winforms_series_1

他们创建一个从IGraphicsDeviceService派生的GraphicsDeviceServiceGraphicsDeviceService更新PresentationParameters并调用graphicsDevices.Reset(parameters); 任何时候GraphicsDevice需要它,这是任何时候窗口或窗体的大小。

从你发布的代码,我猜测camDetails.ShowDialog();SetCellIndex内的SetCellIndex可能是原因。

作为一个快速testing,您可以在调用Logic();之前尝试一下Logic();

 graphicsDeviceService.ResetDevice(ClientSize.Width, ClientSize.Height); 

尝试从您的Systems.Windows.Forms.Control调用