Friday, August 8, 2008

'could not be set on property' error in custom ASP.NET controls

XPanel class in our EasyQuery.NET WebForms project contains the Appearance property of complex type XAppearance. This class has another "complex" property MenuStyle so we got a complex property inside another complex property:
 
public class XPanel : Panel, INamingContainer {
     .  .  .  .  .  .  .  .  .  . 
     private XAppearance appearance = null;

  [DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
      NotifyParentProperty(true)]
  public XAppearance Appearance {
      get {
             return appearance; 
         }
  }
     .  .  .  .  .  .  .  .  .  . 
}

.  .  .  .  .  .  .  .  .  .  .  .  .  .  .

[TypeConverter(typeof(ExpandableObjectConverter))]
public class XAppearance : IStateManager {
    .  .  .  .  .  .  .  .  .  . 
    
 private ScriptMenuStyle scriptMenuStyle;

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
     NotifyParentProperty(true)]
    public ScriptMenuStyle ScriptMenuStyle {
        get {
            return scriptMenuStyle;
        }
    }
    .  .  .  .  .  .  .  .  .  . 
}

.  .  .  .  .  .  .  .  .  .  .  .  .  .  .

[TypeConverter(typeof(ExpandableObjectConverter))]
public class ScriptMenuStyle : Style {
    .  .  .  .  .  .  .  .  .  . 
}

Everything will work OK at run-time. But if you try to change some sub-property of XPanel.Appearance.MenuStyle in visual designer then next time you load this form, Visual Studio will show you the following error message:
"SomeValue" could not be set on property SomeProperty
We have spent several hours trying to find the reason of this error message without any success. Finally we have found the solution but still do not know the source of the problem. The solution is quite simple. We just need to make ScriptMenuStyle property writable:
 
[TypeConverter(typeof(ExpandableObjectConverter))]
public class XAppearance : IStateManager {
    .  .  .  .  .  .  .  .  .  . 
    public ScriptMenuStyle ScriptMenuStyle {
        get {
            return scriptMenuStyle;
        }
  set {
      scriptMenuStyle = value;
  }
    }
    .  .  .  .  .  .  .  .  .  . 
}
Now everything works correctly both at run-time and at design-time but it will be great to get known what was the cause of this problem.