Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialization Issues at Design Time with CustomType Properties Using CustomCodeDomSerializer and CodeExpression in overidden Serialize Method #12754

Open
ChidanandMurugaiah opened this issue Jan 10, 2025 · 7 comments
Assignees
Labels
area-VSDesigner Windows Forms out-of-proc designer related issues

Comments

@ChidanandMurugaiah
Copy link

ChidanandMurugaiah commented Jan 10, 2025

Environment

Visual Studio professional 2022 - version 17.12.0

.NET version

.NET 8

Did this work in a previous version of Visual Studio and/or previous .NET release?

No

Issue description

We are currently working with a custom type property that utilizes a CustomCodeDomSerializer as its DesignerSerializer. Within the CustomCodeDomSerializer class, the CodeExpression is employed in the Serialize method.

However, this implementation is causing serialization issues. Specifically:

When the property value is changed in the property window, the updated code is not generated in the Form1.Designer.cs file.
Upon rebuilding the solution, the changes made in the property window are reverted.
Through design-time debugging, we identified that the Serialize method is not being triggered for property changes. The root cause appears to be the inclusion of the CodeExpression in the serialization logic. When this line is commented out, the Serialize method triggers as expected.

However, in our scenario, the CodeExpression is essential for serializing the data.

We would appreciate any guidance or suggestions on resolving this issue while maintaining the use of CodeExpression in the serialization process.

Demo link - CodeDomSerializerIssue.zip

Steps to reproduce

1.Open the Designer.
2.Click the CustomControl and go to the propertwindow.
3.Expand the ColorCheck (Custom property) and change the Color property.
4.Save the changes and check the form1.Designer.cs page.

Expected Behavior - Changes needs to be added in the Designer.cs page.
Observed Behavior - Changes are not added in the Designer.cs page.

  1. Rebuild the solution and open the property window.

Expected Behavior - Updated values needs to maintain in the property window.
Observed Behavior - property value changes to its Default value.

@ChidanandMurugaiah ChidanandMurugaiah added the untriaged The team needs to look at this issue in the next triage label Jan 10, 2025
@merriemcgaw merriemcgaw removed the untriaged The team needs to look at this issue in the next triage label Jan 14, 2025
@merriemcgaw
Copy link
Member

@Olina-Zhang can you check this on the latest designer versions?

@Olina-Zhang
Copy link
Member

@Olina-Zhang can you check this on the latest designer versions?

that sample application uses the latest designer version, can repro it.

Image

@elachlan elachlan added the area-VSDesigner Windows Forms out-of-proc designer related issues label Jan 17, 2025
@ChidanandMurugaiah
Copy link
Author

@Olina-Zhang , @elachlan, @merriemcgaw, @Shyam-GuptaIs there any update regarding this issue? This problem is currently a code blocker for our case. If the issue has not been resolved yet, are there any alternative solutions we can explore to overcome it?

@Shyam-Gupta
Copy link
Member

@ChidanandMurugaiah I debugged the repro project and found that the Serialize method does get triggered successfully. However, the operation fails due to InvalidCastException at this statement:

CodeExpression codeExpression = (CodeExpression)value;

Looks like we cannot typecast value to CodeExpression.

@Shyam-Gupta
Copy link
Member

Closing this bug as it is not a WinForms issue.

@ChidanandMurugaiah
Copy link
Author

ChidanandMurugaiah commented Feb 5, 2025

Thanks for the update. We have modified the Serialize method by including CodeExpression and ExpressionContext codes. However, the Serialize method is no longer being triggered. I added a Debug.WriteLine statement at the beginning of the method, but it was not executed when CodeExpression was used. Interestingly, if I comment out the line where the CodeExpression value is assigned, the method triggers as expected. Please refer to the modified code snippet below.

public override object Serialize(IDesignerSerializationManager manager, object value)
{
     Debug.WriteLine("Serialize Method triggered");
     ExpressionContext context = null;
     if (manager != null && manager?.Context != null)
         context = manager.Context.Current as ExpressionContext;
     CodeExpression code = new CodeExpression();

     if (context != null)
         code = context.Expression; \\ Issue calling line

     Debug.WriteLine("CodeExpression value assigned");
     return base.Serialize(manager, value);
}

If I comment out the marked line, the method triggers properly.
Analysis Details:
Upon analysis, we found that CodeExpression belongs to the System.CodeDom namespace. This namespace is available in both the default .NET Core assembly and the Microsoft.WinForms.Designer.SDK package.

Image

Image

We suspect that the System.CodeDom namespace is referred from the Microsoft.Winforms.Designer.SDk package after installing that package causing this issue. Is there any possibility to get the System.CodeDom namespace from the Netcore default assemblies. Do you have any ideas that how to resolve that namespace issue for the CodeExpression.

Note: In our scenario, the CodeExpression is essential for data serialization.

Could you please thoroughly analyze this problem and consider reopening the query? This issue is currently a code blocker for our case, and we urgently require a proper solution.
For your reference, I have attached samples that illustrating the issue with this update.

Sample Link - CodeDomSerializerIssue.zip

@Shyam-Gupta
Copy link
Member

Thanks for sharing more information.
The main issue here is that the assembly containing the CustomProperty also contains the corresponding CustomCodeDomSerializer class. This assembly gets loaded in a special UserAssemblyLoadContext in DesignToolsServer process which has been primarily designed to load runtime code of the WinForms app. The design time code should get loaded in the default AssemblyLoadContext.
To do that I would suggest that you structure your solution like this:

  1. First project, say CodeDomSerializationIssue, which includes CustomControl and CustomProperty.
  2. Second project, say DesignTimeAssembly, which includes design time classes such as CustomCodeDomSerializer.
  3. Third project which consumes output assemblies of project (1) and (2) and creates a NuGet package in following format:

Image

To test the changes, create a WinForms .NET project and reference this NuGet package in it. Drag drop CustomControl from the Toolbox and edit the CustomProperty.

Note that name of the assemblies does not matter here. But the directory structure in the NuGet package is important.
The designer scans the NuGet packages referenced by the project and utilizes the directory structure to separate runtime and design time assemblies. It will then load these assemblies in appropriate AssemblyLoadContext in DesignToolsServer process and then everything should work.

For more information, please take a look at following documents:

  1. Control library NuGet package spec: https://github.com/microsoft/winforms-designer-extensibility/blob/main/docs/sdk/control-library-nuget-package-spec.md
  2. Type Editors with the Modern WinForms designer: https://github.com/microsoft/winforms-designer-extensibility/blob/4959e7c5076faf3d8b095db36951fa3c6d77cb79/Templates/TypeEditor/readme.md

I'll reactivate this issue to continue our discussion.

@Shyam-Gupta Shyam-Gupta reopened this Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-VSDesigner Windows Forms out-of-proc designer related issues
Projects
None yet
Development

No branches or pull requests

5 participants