• *****User Control Instance/DataGridView.Columns in Visual Studio Design


    來源:http://www.pcreview.co.uk/forums/user-control-instance-datagridview-columns-visual-studio-design-t2893613.html

    Hi Sorin,

    Thank you for your feedback.

    I am trying to implement a custom collection editor for the inner
    DataGridView columns within a UserControl. The custom collection editor is
    derived from CollectionEditor. The following is the code of the custom
    collection editor.

    using System.ComponentModel.Design;
    using System.Windows.Forms;
    class MyCollectionEditor:CollectionEditor
    {
    public MyCollectionEditor(Type type)
    : base(type)
    { }

    protected override Type CreateCollectionItemType()
    {
    return typeof(DataGridViewColumn);
    }
    protected override Type[] CreateNewItemTypes()
    {
    Type[] types = new Type[] { typeof(DataGridViewTextBoxColumn),
    typeof(DataGridViewComboBoxColumn),
    typeof(DataGridViewCheckBoxColumn),
    typeof(DataGridViewButtonColumn),
    typeof(DataGridViewImageColumn),
    typeof(DataGridViewLinkColumn)};
    return types;
    }

    protected override object CreateInstance(Type itemType)
    {
    DataGridViewColumn column =
    itemType.GetConstructor(Type.EmptyTypes).Invoke(null) as
    DataGridViewColumn;
    return column;
    }
    }

    We need to add an EditorAttribute on the inner DataGridView columns
    property in the UserControl.

    public partial class UserControl1 : UserControl
    {
    [Editor(typeof(MyCollectionEditor),typeof(UITypeEditor))]
    public DataGridViewColumnCollection InnerDGVColumns
    {
    get { return this.dataGridView1.Columns; }
    }
    }

    Thus, I could edit the columns for the DataGridView within the UserControl
    at design-time. However, the problem is that the designer doesn't serialize
    the code of the columns of the DataGridView after I add some columns into
    the DataGridView at design-time.

    I am thinking of using CodeDomSerializer to get the columns serialized
    correctly. Unfortunately, I haven't worked it out yet.

    I will go on researching on this and will get it back to you ASAP. I
    appreciate your patience.

    Sincerely,
    Linda Liu
    Microsoft Online Community Support

    ==============================================

    Linda,
    Can you send me the sample project.
    (E-Mail Removed)

    "Linda Liu [MSFT]" wrote:

    > Hi Sorin,
    >
    > Sorry for my delayed response. I have spent much time researching on how to
    > serialize the inner DataGridView's columns and finally I got it!
    >
    > We need to implement a custom CodeDom serializer for the UserControl. The
    > custom CodeDom serializer derives from CodeDomSerializer class, which is in
    > System.ComponentModel.Design.Serialization namespace. We need to override
    > the Deserialize and Serialize methods in the custom CodeDom serializer
    > class.
    >
    > Generally speaking, when we serialize a component, we use the base
    > serializer for the component to do it. Unfortunately, the base serializers
    > for both the DataGridViewColumnCollection and DataGridViewColumn instance
    > could not serialize them at all. So we have to serialize them by ourselves.
    >
    > System.CodeDom namespace contains classes that can be used to represent the
    > elements and structure of a source code document. CodeDOM is often used by
    > designers to generate initialization code for component.
    >
    > The following is the code of the custom CodeDom serializer.
    >
    > public class MyCodeDomSerializer : CodeDomSerializer
    > {
    >
    > public override object Deserialize(IDesignerSerializationManager
    > manager, object codeObject)
    > {
    > CodeDomSerializer baseClassSerializer =
    > (CodeDomSerializer)manager.GetSerializer(typeof(UserControl1).BaseType,
    > typeof(CodeDomSerializer));
    >
    > return baseClassSerializer.Deserialize(manager, codeObject);
    >
    >
    > }
    >
    > public override object Serialize(IDesignerSerializationManager
    > manager, object value)
    > {
    > CodeDomSerializer baseClassSerializer =
    > (CodeDomSerializer)manager.GetSerializer(typeof(UserControl1).BaseType,
    > typeof(CodeDomSerializer));
    > // serialize the UserControl
    > object codeObject = baseClassSerializer.Serialize(manager,
    > value);
    >
    > if (codeObject is CodeStatementCollection)
    > {
    > CodeStatementCollection statements =
    > (CodeStatementCollection)codeObject;
    >
    > // The code statement collection is valid, so add a comment.
    > string commentText = "This comment was added to this object
    > by a custom serializer.";
    > CodeCommentStatement comment = new
    > CodeCommentStatement(commentText);
    >
    > statements.Insert(0, comment);
    > // serialize the inner DataGridView's columns
    >
    > if (value is UserControl1)
    > {
    > DataGridViewColumnCollection innercolumns = (value as
    > UserControl1).InnerDGVColumns;
    > // declare the variable collection of columns in the
    > inner DataGridView
    > List<CodeVariableReferenceExpression> parameter_list =
    > new List<CodeVariableReferenceExpression>();
    > CodeArrayCreateExpression createArray = null;
    > CodeMethodInvokeExpression methodcall = null;
    >
    > int i = 1;
    >
    > CodeStatementCollection col_Statements = null;
    > foreach (DataGridViewColumn col in innercolumns)
    > {
    > /// serialize each column
    > col_Statements = new CodeStatementCollection();
    >
    > CodeObjectCreateExpression col_ObjectCreate = new
    > CodeObjectCreateExpression(col.GetType());
    >
    > CodeVariableDeclarationStatement
    > col_VariableDeclaration = new
    > CodeVariableDeclarationStatement(col.GetType(), "column" + i.ToString());
    >
    > CodeAssignStatement col_Assign_Create = new
    > CodeAssignStatement(new CodeVariableReferenceExpression("column" +
    > i.ToString()), col_ObjectCreate);
    > // serialize the Width property of the column
    > CodeAssignStatement col_Assign_width = new
    > CodeAssignStatement(new CodeVariableReferenceExpression("column" +
    > i.ToString() + ".Width"), new CodePrimitiveExpression(col.Width));
    >
    > CodeFieldReferenceExpression col_FieldReference =
    > base.SerializeToExpression(manager, col) as CodeFieldReferenceExpression;
    > if (col_FieldReference == null)
    > {
    > col_Statements.Add(col_VariableDeclaration);
    > col_Statements.Add(col_Assign_Create);
    > col_Statements.Add(col_Assign_width);
    > parameter_list.Add(new
    > CodeVariableReferenceExpression("column" + i.ToString()));
    > }
    >
    > ///
    >
    > statements.AddRange(col_Statements);
    > i++;
    > }
    >
    > CodeFieldReferenceExpression target =
    > base.SerializeToExpression(manager, value) as CodeFieldReferenceExpression;
    > // if the designer hasn't all the columns to the inner
    > DataGridView's column collection, add them by ourselves.
    > if (target != null && parameter_list.Count > 0)
    > {
    > createArray = new
    > CodeArrayCreateExpression(typeof(DataGridViewColumn),
    > parameter_list.ToArray());
    > methodcall = new CodeMethodInvokeExpression(new
    > CodeVariableReferenceExpression(target.FieldName + ".InnerDGVColumns"),
    > "AddRange", createArray);
    >
    > statements.Add(methodcall);
    > }
    > }
    > }
    > return codeObject;
    > }
    > }
    >
    > Adorn DesignerSerializerAttribute to the UserControl and
    > DesignerSerializationVisibilityAttribute to the property for the inner
    > DataGridView's columns.
    >
    > [DesignerSerializer(typeof(MyCodeDomSerializer),typeof(CodeDomSerializer))]
    > public partial class UserControl1 : UserControl
    > {
    > public UserControl1()
    > {
    > InitializeComponent();
    > }
    >
    > [Editor(typeof(MyCollectionEditor),typeof(UITypeEditor))]
    >
    > [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    > public DataGridViewColumnCollection InnerDGVColumns
    > {
    > get { return this.dataGridView1.Columns; }
    > }
    > }
    >
    > I also send you with this reply a sample project that contains both the
    > custom UITypeEditor and CodeDom serializer. Please change the attachment's
    > file extension .JPG to .ZIP and unzip it on your machine.
    >
    > Note: in the above sample code and the attached project, I only serialize
    > the Width property of a DataGridView column just for an example. I'm sure
    > you could serialize other proerties for the DataGridView column in the same
    > way.
    >
    > Please try it and let me know if it is what you want.
    >
    >
    > Sincerely,
    > Linda Liu
    > Microsoft Online Community Support
     

  • 相关阅读:
    响应式布局
    bootstrap--前端开发框架
    ADO.NET Entity Framework
    dns
    自动完成脚本
    一个Banner广告收缩效果
    对联广告2
    蓝色经典的对联广告代码
    Js弹性漂浮广告代码
    jquery悬停tab2
  • 原文地址:https://www.cnblogs.com/luoyaoquan/p/2105474.html
Copyright © 2020-2023  润新知