DesignerSerializationVisibility and read-only properties<p align=left>Hello all,</p> <p align=left> </p> <p align=left>According to the MSDN documentation, and if I'm understanding this right, the <strong>DesignerSerializationVisibility</strong> attribute, used with the <strong>DesignerSerializationVisibility.Content</strong> setting, allows you to specify that the value of a property is not serialized per se, and instead, only its <em>contents</em> are serialized.</p> <p align=left>This is used for example for collection properties, which are typically read-only, so that the serializer doesn't serialize the list itself, serializing each item instead. During deserialization, items are deserialized and added to the list via the ICollection interface.</p> <p align=left>But the documentation says that it should work also for any other read-only property: the property's contents (i.e. the property's properties) will be serialized and deserialized. <a title="http://msdn2.microsoft.com/en-us/library/system.componentmodel.designerserializationvisibilityattribute(VS.85).aspx" href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.designerserializationvisibilityattribute(VS.85).aspx">An example of this behaviour is given</a>.</p> <p align=left>However, when using the XamlWriter/XamlReader classes, this doesn't seem to work....</p> <p align=left> </p> <p align=left>Here's my Foo class:</p> <p align=left> </p><font color="#0000ff" size=2><font color="#0000ff" size=2> <p>public</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>class</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>Foo</p></font></font><font size=2> <p>{</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  private</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>string</font></font><font size=2> mName;</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  public</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>string</font></font><font size=2> Name</p> <p>  {</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>    get</font></font><font size=2> { </font><font color="#0000ff" size=2><font color="#0000ff" size=2>return</font></font><font size=2> mName; }</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>    set</font></font><font size=2> { mName = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>value</font></font><font size=2>; }</p> <p>  }</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  private</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>int</font></font><font size=2> mValue;</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  public</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>int</font></font><font size=2> Value</p> <p>  {</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>    get</font></font><font size=2> { </font><font color="#0000ff" size=2><font color="#0000ff" size=2>return</font></font><font size=2> mValue; }</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>    set</font></font><font size=2> { mValue = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>value</font></font><font size=2>; }</p> <p>  }</p> <p>}</p> <p> </p> <p align=left>Here's my FooContainer class:</p> <p align=left> </p><font color="#0000ff" size=2><font color="#0000ff" size=2> <p>public</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>class</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>FooContainer</p></font></font><font size=2> <p>{</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  private</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>Foo</font></font><font size=2> mMyFoo;</p> <p>  [</font><font color="#008080" size=2><font color="#008080" size=2>DesignerSerializationVisibility</font></font><font size=2>(</font><font color="#008080" size=2><font color="#008080" size=2>DesignerSerializationVisibility</font></font><font size=2>.Content)]</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  public</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>Foo</font></font><font size=2> MyFoo</p> <p>  {</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>    get</font></font><font size=2> { </font><font color="#0000ff" size=2><font color="#0000ff" size=2>return</font></font><font size=2> mMyFoo; }</p> <p>  }</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  public</font></font><font size=2> FooContainer()</p> <p>  {</p> <p>    mMyFoo = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>new</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>Foo</font></font><font size=2>();</p> <p>  }</p> <p>}</p></font> <p align=left> </p> <p align=left>Here's my program code:</p> <p align=left> </p><font color="#0000ff" size=2><font color="#0000ff" size=2> <p>static</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>void</font></font><font size=2> Main(</font><font color="#0000ff" size=2><font color="#0000ff" size=2>string</font></font><font size=2>[] args)</p> <p>{</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>  <em>FooContainer</em></font></font><font size=2> f1 = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>new</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>FooContainer</font></font><font size=2>();</p> <p>  f1.MyFoo.Name = </font><font color="#800000" size=2><font color="#800000" size=2>&quot;my foo&quot;</font></font><font size=2>;</p> <p>  f1.MyFoo.Value = 42;</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>  XmlWriterSettings</font></font><font size=2> settings = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>new</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>XmlWriterSettings</font></font><font size=2>();</p> <p>  settings.Indent = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>true</font></font><font size=2>;</p> <p>  settings.NewLineOnAttributes = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>true</font></font><font size=2>;</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  using</font></font><font size=2> (</font><font color="#008080" size=2><font color="#008080" size=2>XmlWriter</font></font><font size=2> writer = </font><font color="#008080" size=2><font color="#008080" size=2>XmlWriter</font></font><font size=2>.Create(</font><font color="#800000" size=2><font color="#800000" size=2>&quot;foo.xml&quot;</font></font><font size=2>, settings))</p> <p>  {</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>    XamlWriter</font></font><font size=2>.Save(f1, writer);</p> <p>  }</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  using</font></font><font size=2> (</font><font color="#008080" size=2><font color="#008080" size=2>XmlReader</font></font><font size=2> reader = </font><font color="#008080" size=2><font color="#008080" size=2>XmlReader</font></font><font size=2>.Create(</font><font color="#800000" size=2><font color="#800000" size=2>&quot;foo.xml&quot;</font></font><font size=2>))</p> <p>  {</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>    FooContainer</font></font><font size=2> f2 = (</font><font color="#008080" size=2><font color="#008080" size=2>FooContainer</font></font><font size=2>)</font><font color="#008080" size=2><font color="#008080" size=2>XamlReader</font></font><font size=2>.Load(reader);</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>    Debug</font></font><font size=2>.Assert(f2.MyFoo.Name == f1.MyFoo.Name);</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>    Debug</font></font><font size=2>.Assert(f2.MyFoo.Value == f1.MyFoo.Value);</p> <p>  }</p> <p>}</p></font> <p align=left> </p> <p align=left>If I <em><strong>don't have</strong></em> the <strong>DesignerSerializationVisibility</strong> attribute on <em>FooContainer.MyFoo</em>, here's the XAML I get:</p> <p align=left> </p><font color="#0000ff" size=2><font color="#0000ff" size=2> <p>&lt;?</font></font><font color="#800000" size=2><font color="#800000" size=2>xml</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>version</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>1.0</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>encoding</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>utf-8</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>?&gt;</p> <p>&lt;</font></font><font color="#800000" size=2><font color="#800000" size=2>FooContainer</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>xmlns</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>clr-namespace:XamlTests;assembly=XamlTests</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2> /&gt;</p></font></font> <p align=left> </p> <p align=left>(obviously, the Asserts fail)</p> <p align=left> </p> <p align=left>If I <strong><em>do have</em></strong> the attribute, here's the XAML I get:</p> <p align=left> </p><font color="#0000ff" size=2><font color="#0000ff" size=2> <p>&lt;?</font></font><font color="#800000" size=2><font color="#800000" size=2>xml</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>version</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>1.0</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>encoding</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>utf-8</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>?&gt;</p> <p>&lt;</font></font><font color="#800000" size=2><font color="#800000" size=2>FooContainer</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>xmlns</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>clr-namespace:XamlTests;assembly=XamlTests</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>&gt;</p> <p>  &lt;</font></font><font color="#800000" size=2><font color="#800000" size=2>FooContainer.MyFoo</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>&gt;</p> <p>    &lt;</font></font><font color="#800000" size=2><font color="#800000" size=2>Foo</p></font></font><font color="#0000ff" size=2><font color="#0000ff" size=2> <p></font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>      Name</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>my foo</font></font><font size=2>&quot;</p></font><font color="#0000ff" size=2><font color="#0000ff" size=2> <p></font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>      Value</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>42</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2> /&gt;</p> <p>  &lt;/</font></font><font color="#800000" size=2><font color="#800000" size=2>FooContainer.MyFoo</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>&gt;</p> <p>&lt;/</font></font><font color="#800000" size=2><font color="#800000" size=2>FooContainer</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>&gt;</p></font></font> <p align=left> </p> <p align=left>...so it seems the attribute works for serialization.... but I get a <strong>XamlParseException</strong> in the <em>XamlReader.Load()</em>, saying that the <em>XamlReader</em> can't deserialize <em>FooContainer.MyFoo</em> because it's read-only.</p> <p align=left> </p> <p align=left>What am I missing? Did I forget to initialize or setup something? Otherwise, what's the point of the <strong>DesignerSerializationVisibility</strong> attribute in this case if you can serialize something to Xaml, but not deserialize it? (which, as far as I can tell, means that piece of Xaml code is useless, except for staring at in notepad, and posting on the MSDN forums).</p> <p align=left> </p> <p align=left>Any help would be appreciated!</font></p>© 2009 Microsoft Corporation. All rights reserved.Tue, 29 Jul 2008 16:44:42 Zc6e3b47b-c5de-43d6-9eb4-50796f278477http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#c6e3b47b-c5de-43d6-9eb4-50796f278477http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#c6e3b47b-c5de-43d6-9eb4-50796f278477lordabdulhttp://social.msdn.microsoft.com/Profile/en-US/?user=lordabdulDesignerSerializationVisibility and read-only properties<p align=left>Hello all,</p> <p align=left> </p> <p align=left>According to the MSDN documentation, and if I'm understanding this right, the <strong>DesignerSerializationVisibility</strong> attribute, used with the <strong>DesignerSerializationVisibility.Content</strong> setting, allows you to specify that the value of a property is not serialized per se, and instead, only its <em>contents</em> are serialized.</p> <p align=left>This is used for example for collection properties, which are typically read-only, so that the serializer doesn't serialize the list itself, serializing each item instead. During deserialization, items are deserialized and added to the list via the ICollection interface.</p> <p align=left>But the documentation says that it should work also for any other read-only property: the property's contents (i.e. the property's properties) will be serialized and deserialized. <a title="http://msdn2.microsoft.com/en-us/library/system.componentmodel.designerserializationvisibilityattribute(VS.85).aspx" href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.designerserializationvisibilityattribute(VS.85).aspx">An example of this behaviour is given</a>.</p> <p align=left>However, when using the XamlWriter/XamlReader classes, this doesn't seem to work....</p> <p align=left> </p> <p align=left>Here's my Foo class:</p> <p align=left> </p><font color="#0000ff" size=2><font color="#0000ff" size=2> <p>public</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>class</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>Foo</p></font></font><font size=2> <p>{</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  private</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>string</font></font><font size=2> mName;</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  public</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>string</font></font><font size=2> Name</p> <p>  {</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>    get</font></font><font size=2> { </font><font color="#0000ff" size=2><font color="#0000ff" size=2>return</font></font><font size=2> mName; }</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>    set</font></font><font size=2> { mName = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>value</font></font><font size=2>; }</p> <p>  }</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  private</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>int</font></font><font size=2> mValue;</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  public</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>int</font></font><font size=2> Value</p> <p>  {</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>    get</font></font><font size=2> { </font><font color="#0000ff" size=2><font color="#0000ff" size=2>return</font></font><font size=2> mValue; }</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>    set</font></font><font size=2> { mValue = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>value</font></font><font size=2>; }</p> <p>  }</p> <p>}</p> <p> </p> <p align=left>Here's my FooContainer class:</p> <p align=left> </p><font color="#0000ff" size=2><font color="#0000ff" size=2> <p>public</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>class</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>FooContainer</p></font></font><font size=2> <p>{</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  private</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>Foo</font></font><font size=2> mMyFoo;</p> <p>  [</font><font color="#008080" size=2><font color="#008080" size=2>DesignerSerializationVisibility</font></font><font size=2>(</font><font color="#008080" size=2><font color="#008080" size=2>DesignerSerializationVisibility</font></font><font size=2>.Content)]</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  public</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>Foo</font></font><font size=2> MyFoo</p> <p>  {</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>    get</font></font><font size=2> { </font><font color="#0000ff" size=2><font color="#0000ff" size=2>return</font></font><font size=2> mMyFoo; }</p> <p>  }</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  public</font></font><font size=2> FooContainer()</p> <p>  {</p> <p>    mMyFoo = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>new</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>Foo</font></font><font size=2>();</p> <p>  }</p> <p>}</p></font> <p align=left> </p> <p align=left>Here's my program code:</p> <p align=left> </p><font color="#0000ff" size=2><font color="#0000ff" size=2> <p>static</font></font><font size=2> </font><font color="#0000ff" size=2><font color="#0000ff" size=2>void</font></font><font size=2> Main(</font><font color="#0000ff" size=2><font color="#0000ff" size=2>string</font></font><font size=2>[] args)</p> <p>{</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>  <em>FooContainer</em></font></font><font size=2> f1 = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>new</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>FooContainer</font></font><font size=2>();</p> <p>  f1.MyFoo.Name = </font><font color="#800000" size=2><font color="#800000" size=2>&quot;my foo&quot;</font></font><font size=2>;</p> <p>  f1.MyFoo.Value = 42;</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>  XmlWriterSettings</font></font><font size=2> settings = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>new</font></font><font size=2> </font><font color="#008080" size=2><font color="#008080" size=2>XmlWriterSettings</font></font><font size=2>();</p> <p>  settings.Indent = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>true</font></font><font size=2>;</p> <p>  settings.NewLineOnAttributes = </font><font color="#0000ff" size=2><font color="#0000ff" size=2>true</font></font><font size=2>;</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  using</font></font><font size=2> (</font><font color="#008080" size=2><font color="#008080" size=2>XmlWriter</font></font><font size=2> writer = </font><font color="#008080" size=2><font color="#008080" size=2>XmlWriter</font></font><font size=2>.Create(</font><font color="#800000" size=2><font color="#800000" size=2>&quot;foo.xml&quot;</font></font><font size=2>, settings))</p> <p>  {</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>    XamlWriter</font></font><font size=2>.Save(f1, writer);</p> <p>  }</p> <p></font><font color="#0000ff" size=2><font color="#0000ff" size=2>  using</font></font><font size=2> (</font><font color="#008080" size=2><font color="#008080" size=2>XmlReader</font></font><font size=2> reader = </font><font color="#008080" size=2><font color="#008080" size=2>XmlReader</font></font><font size=2>.Create(</font><font color="#800000" size=2><font color="#800000" size=2>&quot;foo.xml&quot;</font></font><font size=2>))</p> <p>  {</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>    FooContainer</font></font><font size=2> f2 = (</font><font color="#008080" size=2><font color="#008080" size=2>FooContainer</font></font><font size=2>)</font><font color="#008080" size=2><font color="#008080" size=2>XamlReader</font></font><font size=2>.Load(reader);</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>    Debug</font></font><font size=2>.Assert(f2.MyFoo.Name == f1.MyFoo.Name);</p> <p></font><font color="#008080" size=2><font color="#008080" size=2>    Debug</font></font><font size=2>.Assert(f2.MyFoo.Value == f1.MyFoo.Value);</p> <p>  }</p> <p>}</p></font> <p align=left> </p> <p align=left>If I <em><strong>don't have</strong></em> the <strong>DesignerSerializationVisibility</strong> attribute on <em>FooContainer.MyFoo</em>, here's the XAML I get:</p> <p align=left> </p><font color="#0000ff" size=2><font color="#0000ff" size=2> <p>&lt;?</font></font><font color="#800000" size=2><font color="#800000" size=2>xml</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>version</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>1.0</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>encoding</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>utf-8</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>?&gt;</p> <p>&lt;</font></font><font color="#800000" size=2><font color="#800000" size=2>FooContainer</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>xmlns</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>clr-namespace:XamlTests;assembly=XamlTests</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2> /&gt;</p></font></font> <p align=left> </p> <p align=left>(obviously, the Asserts fail)</p> <p align=left> </p> <p align=left>If I <strong><em>do have</em></strong> the attribute, here's the XAML I get:</p> <p align=left> </p><font color="#0000ff" size=2><font color="#0000ff" size=2> <p>&lt;?</font></font><font color="#800000" size=2><font color="#800000" size=2>xml</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>version</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>1.0</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>encoding</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>utf-8</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>?&gt;</p> <p>&lt;</font></font><font color="#800000" size=2><font color="#800000" size=2>FooContainer</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2> </font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>xmlns</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>clr-namespace:XamlTests;assembly=XamlTests</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>&gt;</p> <p>  &lt;</font></font><font color="#800000" size=2><font color="#800000" size=2>FooContainer.MyFoo</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>&gt;</p> <p>    &lt;</font></font><font color="#800000" size=2><font color="#800000" size=2>Foo</p></font></font><font color="#0000ff" size=2><font color="#0000ff" size=2> <p></font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>      Name</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>my foo</font></font><font size=2>&quot;</p></font><font color="#0000ff" size=2><font color="#0000ff" size=2> <p></font></font><font color="#ff0000" size=2><font color="#ff0000" size=2>      Value</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>=</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2>42</font></font><font size=2>&quot;</font><font color="#0000ff" size=2><font color="#0000ff" size=2> /&gt;</p> <p>  &lt;/</font></font><font color="#800000" size=2><font color="#800000" size=2>FooContainer.MyFoo</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>&gt;</p> <p>&lt;/</font></font><font color="#800000" size=2><font color="#800000" size=2>FooContainer</font></font><font color="#0000ff" size=2><font color="#0000ff" size=2>&gt;</p></font></font> <p align=left> </p> <p align=left>...so it seems the attribute works for serialization.... but I get a <strong>XamlParseException</strong> in the <em>XamlReader.Load()</em>, saying that the <em>XamlReader</em> can't deserialize <em>FooContainer.MyFoo</em> because it's read-only.</p> <p align=left> </p> <p align=left>What am I missing? Did I forget to initialize or setup something? Otherwise, what's the point of the <strong>DesignerSerializationVisibility</strong> attribute in this case if you can serialize something to Xaml, but not deserialize it? (which, as far as I can tell, means that piece of Xaml code is useless, except for staring at in notepad, and posting on the MSDN forums).</p> <p align=left> </p> <p align=left>Any help would be appreciated!</font></p>Mon, 31 Mar 2008 15:56:42 Z2008-03-31T15:56:42Zhttp://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#33cda03d-3210-435c-913a-33f2921720cehttp://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#33cda03d-3210-435c-913a-33f2921720ceDenis Vuykahttp://social.msdn.microsoft.com/Profile/en-US/?user=Denis%20VuykaDesignerSerializationVisibility and read-only properties<p align=left><font face=Arial size=2>You should try marking with DesignerSerializationVisibility attribute your private field that actually contains the value instead of the public getter.</font></p>Mon, 31 Mar 2008 16:43:15 Z2008-03-31T16:43:15Zhttp://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#7692c118-a188-4d59-a12b-2ed74127eb8dhttp://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#7692c118-a188-4d59-a12b-2ed74127eb8dlordabdulhttp://social.msdn.microsoft.com/Profile/en-US/?user=lordabdulDesignerSerializationVisibility and read-only properties<p align=left>Nope.... If I set it only on the private field, I get the first version of the Xaml code (Foo isn't serialized, and my Asserts fail).</p> <p align=left>If I set it on both the private field and the public property, it does the same as when I set it only on the public property (Foo is serialized, but deserialization fails).</p> <p align=left>So I guess it shows that the XamlWriter is really looking for that attribute on public properties, and nothing else.</p>Thanks for the suggestion though.Mon, 31 Mar 2008 17:18:53 Z2008-03-31T17:18:53Zhttp://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#a4b760ca-135f-4737-ba56-84924a262f71http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#a4b760ca-135f-4737-ba56-84924a262f71Denis Vuykahttp://social.msdn.microsoft.com/Profile/en-US/?user=Denis%20VuykaDesignerSerializationVisibility and read-only properties<p align=left><font face=Arial size=2>By the way have you read Mike Hillberg's articles towards XamlWriter?</font></p> <p align=left> </p> <p align=left>Here's the links </p> <p align=left> </p> <p align=left>Being written by XamlWriter</p> <p align=left><a title="http://blogs.msdn.com/mikehillberg/archive/2006/09/16/XamlWriter.aspx" href="http://blogs.msdn.com/mikehillberg/archive/2006/09/16/XamlWriter.aspx">http://blogs.msdn.com/mikehillberg/archive/2006/09/16/XamlWriter.aspx</a></p> <p> </p> <p align=left> </p>Mon, 31 Mar 2008 17:32:04 Z2008-03-31T17:32:04Zhttp://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#c474db2e-ea1a-4c9e-84d2-ac2106549620http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#c474db2e-ea1a-4c9e-84d2-ac2106549620lordabdulhttp://social.msdn.microsoft.com/Profile/en-US/?user=lordabdulDesignerSerializationVisibility and read-only properties<p align=left>Yep, I read it. According to Mike, only collection-type read-only properties are serialized:</p> <p align=left> </p> <blockquote dir=ltr style="margin-right:0px"> <p align=left><span style="font-size:10pt;font-family:'Arial','sans-serif'"><span style="font-size:10pt;font-family:'Arial','sans-serif'"><em>There's usually no point in writing to Xaml the value of a read-only property, because it won't be possible to load it back from the Xaml, since Xaml can't set read-only properties.<span>  </span>There is one case, however, where Xaml can set to a read-only property, and that's with collection type properties.<span>  </span>In that case, it’s not setting the property itself, but adding to the collection.<span></span></em></span></span></p></blockquote> <p align=left> </p> <p align=left>...but this is inconsistent with what the MSDN documentation says, and the example that is given for it... maybe other designer serializers support this attribute completely, but the Xaml one doesn't? That sounds wrong.</p> <p align=left> </p> <p align=left>Then, there's the problem that I <em>can</em> serialize a read-only property, contrary to what Mike Hillberg says (unless by &quot;no point&quot;, he really means &quot;you can do it, but you shouldn't&quot;).... so why is the framework allowing that, if it's not going to allow deserializing it back? Being able to create data you can't use sounds like a huge scenario issue to me, which is why I'm thinking I'm doing something wrong - it could be that the WPF team didn't catch that bug before RTM, but I doubt it.</p> <p> </p> <p align=left>IMHO, there <em>is</em> point in writing the Xaml value of a read-only property: just as, when you deserialize a collection, you get that collection (expecting the object to return a non-null value) and add each item, you could also deserialize a read-only property by getting that property's value from the object (expecting also a non-null value), and then set each of that value's properties.</p> <p align=left>Having a read-only property is a valid OO design decision, and since it looks to me that it's technically possible to implement serialization that works with it, I was hoping that the <strong>DesignerSerializationVisibility</strong> attribute would give me that feature...</p>Mon, 31 Mar 2008 18:05:51 Z2008-03-31T18:05:51Zhttp://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#a1ff6c66-edf7-4ad9-8567-2168883e9248http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#a1ff6c66-edf7-4ad9-8567-2168883e9248lordabdulhttp://social.msdn.microsoft.com/Profile/en-US/?user=lordabdulDesignerSerializationVisibility and read-only properties<p align=left>So I've been digging a bit, and I found that some types in the WPF framework<em> do</em> use read-only properties.</p> <p align=left>For example, <strong>System.Windows.Documents.PageContent</strong> has a read-only property called &quot;<em>Child</em>&quot;, which is exposed to Xaml serialization using <strong>DesignerSerializationVisibility.Content</strong>, and is also set as the content property (via the <strong>ContentProperty</strong> attribute), meaning no wrapping tag will be created in the generated Xaml.</p> <p align=left> </p> <p align=left>So I set my <em>FooContainer</em> class to have its &quot;<em>MyFoo</em>&quot; property be its content property, hoping this would solve my problem.... but I get a different <em>XamlParseException</em>:</p> <p align=left> </p> <blockquote dir=ltr style="margin-right:0px"> <p align=left><em>&quot;Cannot set content property 'MyFoo' on element 'FooContainer'. 'MyFoo' has incorrect access level or its assembly does not allow access. Line '2' Position '66'.&quot;</em></p></blockquote> <p align=left> </p> <p align=left>I don't really know why <em>MyFoo</em> could have an incorrect access level, considering everything is public in this code sample, and I don't know what the second part means, about the assembly not allowing access.</p> <p align=left> </p> <p align=left>Interestingly enough, it looks like what's really happening for the <strong>PageContent</strong> class is that the XamlReader understands the &quot;<em>Child</em>&quot; property as a customized list property behind the scenes. There's an <strong>IAddChild</strong> interface that <strong>PageContent</strong> implements, and which, among other things, is supposed to allow you to serialize and deserialize collections that don't implement the <strong>ICollection</strong> (or is it <strong>IList</strong>?) interface. That sounds a bit weird but it makes sense when you expose a collection only as an <strong>IEnumerable</strong>. To support this, you can implement the <strong>IAddChild</strong> interface, through which the XamlReader will feed you the collection's items.</p> <p align=left> </p> <p align=left>Now, this is funny because I did the test of exposing a read-only <strong>IEnumerable</strong> property, and implementing <strong>IAddChild</strong>, and I get the following exception when deserializing my object:</p> <p align=left> </p> <blockquote dir=ltr style="margin-right:0px"> <p align=left><em>&quot;'ChildFoos' is a read-only IEnumerable property, so 'XamlTests.FooContainer' must implement IAddChild. Line '3' Position '4'.&quot;</em></p></blockquote> <p dir=ltr> </p> <p>It seems that the <strong>IAddChild</strong> interface was deprecated during the betas, but is still around (it was replaced by the <strong>ContentProperty</strong> attribute, but this doesn't really cover all scenarios for the original <strong>IAddChild</strong> interface). The way they deprecated it is by creating an <strong>IAddChildInternal</strong> interface which is, well, internal, and the XamlReader is actually checking for that instead of <strong>IAddChild</strong>. Because the error message was not changed, you get that confusing feedback where the framework tells you that you need to implement an interface you're already implementing... I hope this will be fixed in upcoming patches.</p> <p align=left> </p>Anyway.... it looks like the guys in the WPF framework can serialize/deserialize read-only properties because they're using a half-deprecated/half-internal feature of the SDK... but what about the rest of us? Any information on this from somebody on the WPF team would be very much appreciated.Mon, 31 Mar 2008 23:20:25 Z2008-03-31T23:20:25Zhttp://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#04a7784a-cbec-40c0-9a51-67afaca05209http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c6e3b47b-c5de-43d6-9eb4-50796f278477#04a7784a-cbec-40c0-9a51-67afaca05209Will Sullivanhttp://social.msdn.microsoft.com/Profile/en-US/?user=Will%20SullivanDesignerSerializationVisibility and read-only properties Been awhile, but your IAddChildInternal observation is valuable to me, as I was trying to figure out why the Baml reader didn't recognize my custom collection as implementing the interface.<br><br>Long story short, there are four ways the writer will add content to your content object:  If it implements IDictionary, IList, IAddChild(Internal?!?), or is an ArrayExtension.  So if you're brewing up a custom collection and you want to serialize it to xaml and back, you'd better either implement IDictionary or IList.  <br><br>The good thing is that, if your custom collection is strongly typed, you can implement these explicitly and throw NSE's where appropriate, since all you really care about is the Add method.Tue, 29 Jul 2008 16:44:41 Z2008-07-29T16:44:41Z