Reputation: 1036
THE BACKGROUND
I'm working on custom winforms control. Control incorporates DataGridView control exposed with one of the public properites.
I've implemented custom DesignerActionList and ControlDesigner to have visual inteface for DataGridView columns manipulation (add, remove, change properties values). This works fine: When i add my control to a new form, columns can be added, and are displayed at design time. sceenshot
At the moment i'm about to implement ability to save columns state to {Control}.Designer.cs
I've implemented custom Deisger Serializer as below:
public class GridDesignerSerializer : CodeDomSerializer
{
public override object Serialize(IDesignerSerializationManager manager, object value)
{
var baseSerializer = (CodeDomSerializer)manager.GetSerializer(
typeof(Grid).BaseType,
typeof(CodeDomSerializer));
object codeObject = baseSerializer.Serialize(manager, value);
// now add some custom code
if (codeObject is CodeStatementCollection)
{
// add a custom comment to the code.
var statements = (CodeStatementCollection)codeObject;
statements.Add(new CodeCommentStatement("This is GridDesignerSerializer generated code BEGIN:"));
// HERE COMPONENT INITIALIZATION INVOKES WILL BE PLACED.
statements.Add(new CodeCommentStatement("This is GridDesignerSerializer generated code :END"));
}
return codeObject;
}
}
And additional Control Class serialization attribute:
[Designer(typeof(Grid_Designer))]
[DesignerSerializer(typeof(GridDesignerSerializer), typeof(CodeDomSerializer))]
public partial class Grid : UserControl
{ ...
THE PROBLEM
When i add new column to incorporated inside my custom control DataGridView at design time, no changes are detected by designer (vs document tab has no *). So when i close the design view serialization is not taking place.
When i change one of other control properties (lets say: change border style) changes are detected and custom serialization is executed (additional comment shows inside designer).
THE QUESTION
How to notify Desiger that changes where made (columns where added), and execute serialization?
Inside GridDesignerSerializer
how to reffer to design time DataGridView instance to iterate over added columns to perform code generation?
Thanks for any suggestions.
Upvotes: 2
Views: 993
Reputation: 1036
OK, I think point 1 is solved with below:
I've added Inside my control class:
private IComponentChangeService GetChangeService()
{
return (IComponentChangeService)GetService(typeof(IComponentChangeService));
}
And then inside the method / property that is responsible for change detection:
this.GetChangeService().OnComponentChanged(this, null, null, null);
As a result when I add a column to DataGridView, the * shows on document tab, and after saving custom serialization is performed.
Point 2 also:
In my case, add below code inside GridDesignerSerializer
:
var grid = ((Grid)value);
statements.Add(new CodeCommentStatement("Column Count:" + grid.List.Columns.Count.ToString()));
Generally instance of serialized object is second argument of Serialize
Method:
Serialize(IDesignerSerializationManager manager, object value)
Upvotes: 2