1

I wrote a TextBox which checks its text for validity. The method to check the text is provided by the caller as a System.Func<string, bool>. The simplified code looks like this:

public class ValidTextBox : System.Windows.Forms.TextBox
{
    public System.Func<string, bool> IsValid { get; set; }
}

I used it successfully for several things, but then I tried to provide a nonstatic method. The code compiles fine but Visual Studio's Designer throws an lengthy exception whenever I try to drag it from the Toolbox into a Form (see below).

public class SpecialTextBox : ValidTextBox
{
    public SpecialTextBox()
    {
        base.IsValid = s => true; // works
        base.IsValid = StaticReturnTrue; // works
        base.IsValid = s => StaticReturnTrue(s); // works
        base.IsValid = this.ReturnTrue; // doesn't work
        base.IsValid = s => this.ReturnTrue(s); // doesn't work
    }

    private static bool StaticReturnTrue(string s)
    {
        return true;
    }

    private bool ReturnTrue(string s)
    {
        return true;
    }
}

I can't copy and paste the text of a MessageBox so please excuse typos. The language is german:

Fehler beim Erstellen der Komponente SpecialTextBox. Die Fehlermeldung: System.Runtime.Serialization.SerializationException: Der Typ "GuiTest.SpecialTextBox" in Assembly "GuiTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" ist nicht als serialisierbar gekennzeichnet.
bei System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
bei System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContent content)
bei System.Runtime.Serialization.FormatterServices.Binary.WriteObjectInfo.InitMemberInfo()
bei System.Runtime.Serialization.FormatterServices.Binary.WriteObjectInfo.InitSerialze([...]) bei System.Runtime.Serialization.FormatterServices.Binary.ObjectWriter.Write([...])

If I mark SpecialTextBox as [System.Serializable] the designer complains that ValidTextBox is not marked as serializable. If I then mark ValidTextBox as [System.Serializable] the designer complains that System.Windows.Forms.TextBox is not marked as serializable, which I can't change.

Why does the designer get an exception?

How can I provide a nonstatic method at runtime?

Karsten Gutjahr
  • 316
  • 2
  • 12
  • What do you mean by "doesn't work"? What *exactly* is the exception? – Jon Skeet Oct 22 '14 at 12:16
  • I'd guess you forgot to [check for design time](http://stackoverflow.com/q/2427381/1997232) in your self-made control. Also, mark that property [non serializable](http://stackoverflow.com/q/2598733/1997232). – Sinatr Oct 22 '14 at 12:49
  • @Sinatr: Putting it into `if(!DesignMode) { }` doesn't help... – Karsten Gutjahr Oct 22 '14 at 13:02

1 Answers1

3

It tries to serialize the property value because it has a non-null value. That cannot come to a good end, the hidden class that the C# compiler generated to implement the lambda (the type of the target object of the delegate) is not serializable. Which is an issue when it needs to capture state, like the this reference that's needed to properly call the ReturnTrue() method.

The fix is simple, you don't need it serialized since you always initialize it at runtime. So use attributes to stop it:

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public System.Func<string, bool> IsValid { get; set; }
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536