Sample XNA code to establish a fixed size windowed view
public Game1()
{
graphics = new GraphicsDeviceManager(this);
// Determine the resolution of the screen
int maxwidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
int maxheight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
// Set the game window to 90% of the avaiable resolution
_windowWidth = (int) (0.9*maxwidth);
_windowHeight = (int) (0.9*maxheight);
graphics.PreferredBackBufferWidth = _windowWidth;
graphics.PreferredBackBufferHeight = _windowHeight;
// Block window size
Window.AllowUserResizing = false;
Content.RootDirectory = "Content";
}
Alternatively, you can allow user resizing and create a callback to your application to cope with the changed size.
Window.AllowUserResizing = true; Window.ClientSizeChanged += WindowClientSizeChanged;
and the handler
private void WindowClientSizeChanged(object sender, EventArgs e) // change resolution after resize
{
_graphics.PreferredBackBufferWidth = GraphicsDevice.Viewport.Width;
_graphics.PreferredBackBufferHeight = GraphicsDevice.Viewport.Height;
_graphics.ApplyChanges();
}
Update:
With recent monogame versions the call to ApplyChanges(); will cause a stack overflow because the application of the change starts the loop over and over again. To bypass this, you can pass a boolean to your update method to indicate that the screen size has changed and needs updating.
The adapted code is as follows:
private void WindowClientSizeChanged(object sender, EventArgs e) {
_graphics.PreferredBackBufferWidth = Window.ClientBounds.Width;
_graphics.PreferredBackBufferHeight = Window.ClientBounds.Height;
_windowSizeUpdatePending = true;
}
protected override void Update(GameTime gameTime) {
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) {
Exit();
}
if (_windowSizeUpdatePending) {
_windowSizeUpdatePending = false;
_graphics.ApplyChanges();
}
base.Update(gameTime);
}