Why does this class fail to draw to a texture twice?

I’ve got a monogame project going where I want to generate lots of moving sprites that are a single letter. Think the interface of Dwarf Fortress in opengl.
I’ve written a class that runs at startup to create a series of textures from character strings. I could load up all the textures from static images, but I’d rather have the flexibility of being able to quickly add a new sprite by just picking a character and running with it.
The class works just fine for the first texture, but the second texture comes back completely blank.

The class is this:

   class Text2Texture  //Class to generate 32x32 textures generated from a character string.
{
    GraphicsDevice graphics;
    ContentManager content;
    SpriteBatch spriteBatch;
    SpriteFont fontRender;
    RenderTarget2D scratchTexture;


    public Text2Texture(GraphicsDevice gd, ContentManager cm, SpriteBatch sb)
    {
        graphics = gd;
        spriteBatch = sb;
        content = new ContentManager(cm.ServiceProvider, cm.RootDirectory);
        fontRender = content.Load<SpriteFont>("PCSenior");
        scratchTexture = new RenderTarget2D(graphics, 32, 32, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.PreserveContents);
    }

    public Texture2D generateTextureBox(string text)
    {
        //Setup to draw on an unseen rendertarget.
		graphics.SetRenderTarget(scratchTexture); 
        graphics.Clear(Color.Transparent);
        
		//Draw the text onto a rendertarget to create the texture.
		spriteBatch.Begin();
        Vector2 FontOrigion = fontRender.MeasureString(text) / 2;
        spriteBatch.DrawString(fontRender, text, new Vector2(16, 18), Color.Black, 0, FontOrigion, 1.0f, SpriteEffects.None, 0.5f);            
        spriteBatch.End();
        
		//Make a copy of the data onto the new texture.  
		Texture2D finalTexture = new Texture2D(graphics, scratchTexture.Width, scratchTexture.Height);            
		Color[] texdata = new Color[scratchTexture.Width * scratchTexture.Height];                
		scratchTexture.GetData(texdata);
		finalTexture.SetData(texdata);
        
        graphics.SetRenderTarget(null);

        return finalTexture;
    }

}

Then under game1.cs I have this in under LoadContent:

TextureA = t2t.generateTextureBox("A");  //A is drawn
TextureB = t2t.generateTextureBox("B"); //B never shows up.

The draw is equally straightforward. Under Draw I have:

    spriteBatch.Draw(TextureA, new Vector2(20, 20), null, Color.Black, 0f, new Vector2(16, 16), 1f, SpriteEffects.None, 1);
    spriteBatch.Draw(TextureB, new Vector2(50, 50), null, Color.Black, 0f, new Vector2(16, 16), 1f, SpriteEffects.None, 1);

Stepping through the code, it seems that point of failure is at the spriteBatch.DrawString(…) step. It simply isn’t drawing anything.

I’ve monkeyed with the code quite a bit trying to figure this out.
One change I tried is to dispose the scratchtexture after the copy and create a new one each time. When I do that, the first texture is created correctly, the second one is created, but it shows up as a black box (The alpha transparency is drawn incorrectly.)
I’ve also tried passing in the graphics device to the generateTextureBox method instead of when I instantiate the class, that doesn’t help.

Any suggestions here?

Ahhh HA! After banging on this for 9 days I finally stumbled across the solution.
I’ll post it here in case anyone else runs into this issue.
Anyway, I tried numerous debugging items just trying to get this to work. Even loading up Object exporter to dump the contents of the SpriteBatch and GraphicsDevice and crawl through object to see what’s changed between the first draw, and the second draw.

I noticed that in the second draw of the SpriteBatch, this field had strange values:

_tempRect = {X:164 Y:97 Width:18 Height:21} [Microsoft.Xna.Framework.Rectangle]

For a 32x32 texture, that’s off screen.

So then I added in a simple Draw statement to draw 2x2 pixel just to see if it was even drawing anything. Lo and behold, that actually fixed the issue. Dumping the objects, the only change I could find to the spritebatch object is it changes the tempRect to this:

_tempRect = {X:0 Y:0 Width:2 Height:2} [Microsoft.Xna.Framework.Rectangle]

Maybe it’s a bug in monogame, but it seems that if you do nothing but DrawString and never draw anything else, it’ll behave very oddly for all subsequent draws.

The exact fix is to add this line:

spriteBatch.Draw(PixelDot, new Vector2(2, 2), Color.Transparent); //Doesn't draw anything visible - just fixes spritebatch

Before the spriteBatch.End();