Keep editor alive after bad text change?


#1

I’d like to make my node labels editable but be able to prevent invalid changes. When the user attempts an invalid change, I’d like to display an error dialog, then allow them to correct the error without hiding the editor that was being used.
I’ve tried subclassing GoText and overriding DoEdit, but haven’t hit on the behavior I’m looking for. It’s like I’d like to have GoText.DoEdit return a bool instead of a void, where “false” means “don’t apply the change and keep the edit alive”.
Any ideas on a good way to accomplish this?
Any help greatly appreciated.
Mike D


#2

That sounds like a good suggestion, although it will take a lot of research and experimentation to find out if that will work in all cases on all platforms. And then there are compatibility issues…
The most general thing you can do now is to override GoText.CreateEditor, to have it return a GoControl object whose ControlType refers to a TextBox subclass that you define. Maybe:
public override GoControl CreateEditor(GoView view) {
GoControl editor = base.CreateEditor(view);
editor.ControlType = typeof(YourTextBox);
return editor;
}
Then define YourTextBox. Here’s the (simplified) definition that GoText uses:
public class YourTextBox : System.Windows.Forms.TextBox, IGoControlObject { // nested class
public YourTextBox() {}
public GoControl GoControl {
get { return myGoControl; }
set {
GoControl old = myGoControl;
if (old != value) {
myGoControl = value;
if (value != null) {
GoText gotext = value.EditedObject as GoText;
if (gotext != null) {
this.Text = gotext.Text;
// do other initialization of YourTextBox here!
}
}
}
}
}
public GoView GoView {
get { return myGoView; }
set { myGoView = value; }
}
protected override bool ProcessDialogKey(System.Windows.Forms.Keys key) {
if (HandleKey(key))
return true;
else
return base.ProcessDialogKey(key);
}
protected override void OnLeave(EventArgs evt) {
GoControl ctrl = this.GoControl;
if (ctrl != null) {
GoText gotext = ctrl.EditedObject as GoText;
if (gotext != null) {
gotext.DoEdit(this.GoView, gotext.Text, this.Text);
}
ctrl.DoEndEdit(this.GoView);
}
base.OnLeave(evt);
}
private bool HandleKey(System.Windows.Forms.Keys key) {
if (key == System.Windows.Forms.Keys.Escape) {
// change code here!
GoControl ctrl = this.GoControl;
if (ctrl != null)
ctrl.DoEndEdit(this.GoView);
this.GoView.Focus();
return true;
} else if (key == System.Windows.Forms.Keys.Enter || key == System.Windows.Forms.Keys.Tab) {
if (key == System.Windows.Forms.Keys.Enter && this.AcceptsReturn) // accept the return to start a new line
return false;
// change code here!
GoControl ctrl = this.GoControl;
if (ctrl != null) {
GoText gotext = ctrl.EditedObject as GoText;
if (gotext != null) {
gotext.DoEdit(this.GoView, gotext.Text, this.Text);
}
ctrl.DoEndEdit(this.GoView);
this.GoView.Focus();
}
return true;
} else {
return false;
}
}
// YourTextBox state
private GoControl myGoControl = null;
private GoView myGoView = null;
} // end of YourTextBox
Besides finishing the initialization of the YourTextBox when the GoControl is set, you’ll want to define your Validating event handler, and modify the code so that it doesn’t blindly call GoControl.DoEndEdit and GoView.Focus.
I hope this is enough to get you started. For another example of defining a custom editor for a GoObject, you might want to take a look at Demo1’s RectangleWithCheckBoxEditor, in the RectWithCheckBox.cs/.vb file. This inherits from GoRectangle instead of GoText, so it has more to define on that class, but the Control part is similar.


#3

Thanks once again Walter for taking the time to put together an answer. I can see how learning to do this will be useful for other things too. I’ll take a crack at it.
MD