GoText editor: dynamic expansion

I wonder if I can resize GoText editor’s boundaries during text editing.

When using this code:
public class CustomTextNode : GoText
{
public override void DoBeginEdit(GoView view)
{
base.DoBeginEdit(view);

if (this.Editor == null)
return;

var control = this.Editor.GetControl(view);

if (control != null)
control.TextChanged += (sender, args) =>
{
var textWidth = TextRenderer.MeasureText(control.Text, control.Font).Width;
if (control.Width < textWidth)
control.Width = textWidth;
};
}
}

TextBox stays expanded until it will be refreshed. After that it backs to initial boundaries’ size.

You want the TextBox control to grow and shrink automatically as the user types each key?

I played with your class a bit… I see the size of the TextBox grow and shrink as I type every other character (and the “shrink” shouldn’t be happening).

this line -> control.Width = textWidth;


will change control.Width to 504 from 472 (for example), but the next keystroke finds the control.Width set back to 472 again.


There’s nothing in our TextBoxControl code that does that, so it appears something in .NET is fighting with you here.


I tried control.Bounds and control.ClientSize but couldn’t get any more reasonable behavior out of it.

But when I try it on a simple Form without GoDiagram I have no such a problem.

Besides if I move cursor over TextBoxControl and it’s going to shrink back I see such CallStack:

TextBlock.exe!TextBlock.CustomTextBox.SetBoundsCore(int x, int y, int width, int height, System.Windows.Forms.BoundsSpecified specified) Line 40 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.SetBounds(int x, int y, int width, int height, System.Windows.Forms.BoundsSpecified specified) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.Bounds.set(System.Drawing.Rectangle value) Unknown
Northwoods.Go.dll!Northwoods.Go.GoControl.Paint(System.Drawing.Graphics g, Northwoods.Go.GoView view) Unknown
Northwoods.Go.dll!Northwoods.Go.GoLayer.Paint(System.Drawing.Graphics g, Northwoods.Go.GoView view, System.Drawing.RectangleF clipRect) Unknown
Northwoods.Go.dll!Northwoods.Go.GoView.PaintObjects(bool doc, bool view, System.Drawing.Graphics g, System.Drawing.RectangleF clipRect) Unknown
Northwoods.Go.dll!Northwoods.Go.GoView.PaintView(System.Drawing.Graphics g, System.Drawing.RectangleF clipRect) Unknown
Northwoods.Go.dll!Northwoods.Go.GoView.onPaintCanvas(System.Windows.Forms.PaintEventArgs evt) Unknown
Northwoods.Go.dll!Northwoods.Go.GoView.OnPaint(System.Windows.Forms.PaintEventArgs evt) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.PaintWithErrorHandling(System.Windows.Forms.PaintEventArgs e, short layer) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.OnPrint(System.Windows.Forms.PaintEventArgs e) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.WmPrintClient(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) Unknown
[Native to Managed Transition]

And code throws an exception when another graphical goobject appears under that TextBoxControl:
Message: Parameter is not valid.
StackTrace:
at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
at System.Drawing.Graphics.DrawImage(Image image, Rectangle destRect, Rectangle srcRect, GraphicsUnit srcUnit)
at Northwoods.Go.GoViewLicenseProvider.GoViewLicense.Dispose(GoView view)
at Northwoods.Go.GoView.onPaintCanvas(PaintEventArgs evt)
at Northwoods.Go.GoView.OnPaint(PaintEventArgs evt)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Maybe you can suggest any solution of that?

You’re right… I missed the Bounds setting down in GoControl.Paint. I’m actually not sure why that’s there.

OK… Some hackery follows to create a Custom GoControl for the custom GoText. It works, but I’d recommend more testing than the 10 minutes I spent on this.

// grow text editor field as the user types.

[Serializable]
public class CustomTextNode : GoText
{
public override void DoBeginEdit(GoView view)
{
base.DoBeginEdit(view);

      if (this.Editor == null)
          return;

      var control = this.Editor.GetControl(view);
      TextBox tb = control as TextBox;

      if (control != null)
          control.TextChanged += (sender, args) =>
          {
              var textWidth = TextRenderer.MeasureText(control.Text, control.Font).Width + 20;
              //if (control.Width < textWidth)
              //{
              //    control.Width = textWidth;
              //}
              if (tb.Bounds.Width < textWidth)
              {
                   tb.Bounds = new Rectangle(tb.Bounds.Location, new Size(textWidth, tb.ClientSize.Height));
              }
          };
  }

  public override GoControl CreateEditor(GoView view)
  {
      float wsw = 1;
      float wsh = 1;

    // assume this.EditorStyle == GoTextEditorStyle.TextBox
    GoControl editorX = base.CreateEditor(view);
    GoControl editor = new GoControlNoPaint();

    // this is a gross hack to get around internal type for text editor controltype.

    editor.ControlType = editorX.ControlType;
    editor.Bounds = editorX.Bounds;

    return editor;

  }

}

public class GoControlNoPaint : GoControl
{

  public override void Paint(Graphics g, GoView view)
  {
      System.Windows.Forms.Control comp = GetControl(view);
      if (comp != null)
      {
          //RectangleF docrect = this.Bounds;
          //Rectangle viewrect = view.ConvertDocToView(docrect);
          //if (!(comp is GoText.ComboBoxControl))
          //{
          //    comp.Bounds = viewrect;
          //}
          if (!comp.Visible) comp.Visible = true;
      }

  }

}

Everything Ok now. Many thanks!