Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ToolStripControlHost托管用户控件设计器序列化WIN';不会发生_C#_.net_Visual Studio_Winforms_Serialization - Fatal编程技术网

C# ToolStripControlHost托管用户控件设计器序列化WIN';不会发生

C# ToolStripControlHost托管用户控件设计器序列化WIN';不会发生,c#,.net,visual-studio,winforms,serialization,C#,.net,Visual Studio,Winforms,Serialization,我目前正在开发一个应用程序,希望在上下文菜单中显示UserControl。我能够(使用ToolStripControlHost在某种程度上实现这一点)。如(NumericUpDownToolStripItem代码)所示:下面是对象的代码(用VC++.net 2.0编写)。注意:在这方面有一些半相似的问题,但似乎没有一个是关于序列化usercontrols的,只是usercontrols中的标准对象 对象后面显示的是实际usercontrol的代码,它是一个带标签的usercontrol和一个nu

我目前正在开发一个应用程序,希望在上下文菜单中显示UserControl。我能够(使用ToolStripControlHost在某种程度上实现这一点)。如(NumericUpDownToolStripItem代码)所示:下面是对象的代码(用VC++.net 2.0编写)。注意:在这方面有一些半相似的问题,但似乎没有一个是关于序列化usercontrols的,只是usercontrols中的标准对象

对象后面显示的是实际usercontrol的代码,它是一个带标签的usercontrol和一个numericupdown控件

问题是:当我为我的应用程序加载设计器时,我可以添加NumericUpDownToolStripItem,但是,当我打开use The exposed Property来编辑我的usercontrol时,没有一个数据被序列化到NumericUpDownToolStripItem对象的InitializeComponent方法中。其效果是我的控件在运行时加载所有默认值。每次我重新加载表单时,修改都会丢失

我曾尝试使用找到的TypeConverter教程,但没有正常工作。一切都编译得很好,除了我的对象在设计网格中完全变灰(只是accessor属性,而不是整个menupic)。我注意到的另一个问题是,这个方法不是专门为UserControls设计的,UserControls可能有几个不同的可修改属性,并且不可能每个属性都有重载

因此,我有以下问题:

  • 我所做的是实际的,还是我的结构偏离了规范。我确信属性中有很多冗余
  • 序列化另一个usercontrol\toolstriphost“parent”中包含的usercontrol“child”的正确方法是什么。“child”中的任何属性都是简单值(字符串、小数等)
  • 当TypeConverter类未实现时,每次我更改属性(例如标签文本)时,对象的绘制都会变得异常,直到我重新发布上下文\菜单或表单。因为我做了改变,有没有合适的方法通知设计师重新粉刷?(我使用了invalidate,它充其量也不可靠)
  • 提前谢谢。我将继续对此进行研究,并不断更新问题

    NumericUpDownToolStripItem Class:
        [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability::All)]
        public ref class NumericUpDownToolStripItem : public ToolStripControlHost
        {
           public: 
           [DesignerSerializationVisibility(DesignerSerializationVisibility::Content | 
              DesignerSerializationVisibility::Visible)]
           property LabeledNumericUpDown ^LabeledNumericUpDownControl
           {
             LabeledNumericUpDown ^get() { return (LabeledNumericUpDown^)this->Control; }
           }
    
           public: NumericUpDownToolStripItem(void) : 
              ToolStripControlHost(gcnew LabeledNumericUpDown()) {}
    
           protected: void OnSubscribeControlEvents(Control ^control) new  { //irrelevant to question }
           protected: void OnUnsubscribeControlEvents(Control ^control) new { //irrelevant to question }       
        };
    
    public ref class LabeledNumericUpDown : public UserControl
    {
       public: [ DesignerSerializationVisibility(DesignerSerializationVisibility::Content | 
        DesignerSerializationVisibility::Visible)]
       property String ^DisplayText {
          String ^get() {
             return this->label->Text;
          }
          void set(String ^val) {
             if(this->label->Text != val)
             {
                this->label->Text = val;
                this->Invalidate();
             }
          }
       }
    
    //constructor
    //destructor
    //initiailecomponent
    };
    

    好吧,经过多次搜索,我找到了答案。我的方法很好,除了一个主要问题:我根本不需要类型转换器。我的问题是需要一个定制的CodeDomConverter。下面是我的解决方案

        generic<typename T>
        ref class CustomCodeDomSerializer : CodeDomSerializer
        {
        public: virtual Object ^Deserialize(IDesignerSerializationManager ^manager, Object ^codeObject) override
           {
              // This is how we associate the component with the serializer.
              CodeDomSerializer ^baseClassSerializer = (CodeDomSerializer^)manager->
                 GetSerializer(T::typeid->BaseType, CodeDomSerializer::typeid);
    
               //This is the simplest case, in which the class just calls the base class
               //   to do the work. 
              return baseClassSerializer->Deserialize(manager, codeObject);
           }
    
           public: virtual Object ^Serialize(IDesignerSerializationManager ^manager, Object ^value) override
           {
               //Associate the component with the serializer in the same manner as with
               //   Deserialize 
              CodeDomSerializer ^baseClassSerializer = (CodeDomSerializer^)manager->
                 GetSerializer(T::typeid->BaseType, CodeDomSerializer::typeid);
    
              Object ^codeObject = baseClassSerializer->Serialize(manager, value);
    
               //Anything could be in the codeObject.  This sample operates on a
               //   CodeStatementCollection. 
              if (dynamic_cast<CodeStatementCollection^>(codeObject))
              {
                 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 = gcnew CodeCommentStatement(commentText);
                 statements->Insert(0, comment);
              }
              return codeObject;
           }
    
    };
    
    
    
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    ///   <summary>   
    ///   This Usercontrol is a simple label coupled with a numericupdown.  The class following
    ///   it will wrap this item in toolstrip container so that it can be part of a contextmenu
    ///   </summary>
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    [DesignerSerializer(CustomCodeDomSerializer<LabeledNumericUpDown^>::typeid, CodeDomSerializer::typeid)]
    public ref class LabeledNumericUpDown : UserControl
    {
       public: event EventHandler ^NumericUpDownValueChanged;
    
       public: [Category("Custom Information"), Description(L"Text to display"), 
                DefaultValue(L"Default Text"), Browsable(true), Localizable(true), NotifyParentProperty(true)]
       property String ^DisplayText
       {
          String ^get()
          {
             return this->label->Text;
          }
          void set(String ^val)
          {
             this->label->Text = val;
             if(this->DesignMode || 
                LicenseManager::UsageMode == LicenseUsageMode::Designtime) 
                this->Invalidate();
    
          }
       }
      //designer stuff not important
    }
    
    
    
    
    [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability::All),
     ToolboxBitmap(::NumericUpDown::typeid)]
    public ref class NumericUpDownToolStripItem : ToolStripControlHost
    {
       //replace this type
       private: LabeledNumericUpDown ^_Control;
    
       public: [Category("Object Host"), Description(L"Hosted usercontrol object"), 
        DisplayName("UserControl Object"), Browsable(true), NotifyParentProperty(true),
        DesignerSerializationVisibility(DesignerSerializationVisibility::Content)]
        //replace this properties type
       property LabeledNumericUpDown ^UserControlObject
       {
         //replace this properties return type
         LabeledNumericUpDown ^get() { return this->_Control; }
       } 
    
       public: NumericUpDownToolStripItem(void) : 
          System::Windows::Forms::ToolStripControlHost(gcnew FlowLayoutPanel())
        { 
          //replace this constructor type
          _Control = gcnew LabeledNumericUpDown();
    
          //don't touch this
          FlowLayoutPanel ^thePanel = (FlowLayoutPanel ^)this->Control;
          thePanel->BackColor = Color::Transparent;
          thePanel->Controls->Add(_Control);
       }   
    };
    
    通用
    ref类CustomCodeDomSerializer:CodeDomSerializer
    {
    public:virtual Object^反序列化(IDesignerSerializationManager^管理器,Object^ codeObject)重写
    {
    //这就是我们将组件与序列化程序关联的方式。
    CodeDomainSerializer^baseClassSerializer=(CodeDomainSerializer^)管理器->
    GetSerializer(T::typeid->BaseType,CodeDomSerializer::typeid);
    //这是最简单的情况,在这种情况下,类只调用基类
    //做这项工作。
    返回baseClassSerializer->反序列化(管理器,codeObject);
    }
    公共:虚拟对象^Serialize(IDesignerSerializationManager^manager,对象^value)重写
    {
    //以与相同的方式将组件与序列化程序关联
    //反序列化
    CodeDomainSerializer^baseClassSerializer=(CodeDomainSerializer^)管理器->
    GetSerializer(T::typeid->BaseType,CodeDomSerializer::typeid);
    对象^codeObject=baseClassSerializer->Serialize(管理器,值);
    //codeObject中可能有任何内容。此示例在
    //CodeStatementCollection。
    if(动态_转换(codeObject))
    {
    CodeStatementCollection^语句=(CodeStatementCollection^)codeObject;
    //代码语句集合有效,请添加注释。
    String^commentText=“此注释是由自定义序列化程序添加到此对象的。”;
    CodeCommentStatement^comment=gcnew CodeCommentStatement(commentText);
    语句->插入(0,注释);
    }
    返回代码对象;
    }
    };
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    ///      
    ///此Usercontrol是一个简单的标签,与数字UpDown相结合。下面的班级
    ///它会将此项包装在toolstrip容器中,以便它可以成为上下文菜单的一部分
    ///   
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    [DesignerSerializer(CustomCodeDomainSerializer::typeid,CodeDomainSerializer::typeid)]
    公共引用类LabeledNumericUpDown:UserControl
    {
    public:事件事件处理程序^NumericUpDownValueChanged;
    公共:[类别(“自定义信息”)、说明(L“要显示的文本”),
    DefaultValue(L“默认文本”)、可浏览(true)、可本地化(true)、NotifyParentProperty(true)]
    属性字符串^DisplayText
    {
    字符串^get()
    {
    返回此->标签->文本;
    }
    无效集(字符串^val)
    {
    此->标签->文本=val;
    如果(此->设计模式| |
    LicenseManager::UsageMode==LicenseSusageMode::Designtime)
    此->无效();
    }
    }
    //设计师的东西不重要
    }
    [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability::All),
    ToolboxBitmap(::NumericUpDown::typeid)]
    公共引用类NumericUpDownToolStripItem:ToolStripControlHost
    {
    //替换此类型
    私有:LabeledNumericUpDown^控制;
    public:[类别(“对象主机”),描述(L“托管用户控制对象”),
    DisplayName(“UserControl对象”)、可浏览(true)、NotifyParentProperty(true),
    DesignerSerializationVisibility(DesignerSerializationVisibility::Content)]
    //替换这个p
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    ///   <summary>   
    ///   This Usercontrol is a simple label coupled with a numericupdown.  The class following
    ///   it will wrap this item in toolstrip container so that it can be part of a contextmenu
    ///   </summary>
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    [DesignerSerializer(CustomCodeDomSerializer<LabeledNumericUpDown^>::typeid, CodeDomSerializer::typeid)]
    public ref class LabeledNumericUpDown : UserControl
    {
       public: event EventHandler ^NumericUpDownValueChanged;
    
       public: [Category("Custom Information"), Description(L"Text to display"), 
                DefaultValue(L"Default Text"), Browsable(true), Localizable(true), NotifyParentProperty(true)]
       property String ^DisplayText
       {
          String ^get();
          void set(String ^val);
       }
    
       public: [Category("Custom Information"), Description(L"NumericUpDown Value"), 
                DefaultValue(1), Browsable(true), Localizable(true), NotifyParentProperty(true)]
       property Decimal UpDownValue
       {
          Decimal get();
          void set(Decimal val);
       }
    
       public: [Category("Custom Information"), Description(L"NumericUpDown Maximum"), 
                DefaultValue(100), Browsable(true), Localizable(true), NotifyParentProperty(true)]
       property Decimal UpDownMaximum
       {
          Decimal get();
          void set(Decimal val);
       }
    
       public: [Category("Custom Information"), Description(L"NumericUpDown Minimum"), 
                DefaultValue(0), Browsable(true), Localizable(true), NotifyParentProperty(true)]
       property Decimal UpDownMinimum
       {
          Decimal get();
          void set(Decimal val);
       }
    
       private: bool SupressEvents;
       public: Void UpDownValueSet_NoEvent(int Val);
       private: Void numericUpDown_ValueChanged(Object ^sender, EventArgs ^e);
       public: LabeledNumericUpDown(void);
       private: System::Windows::Forms::NumericUpDown^  numericUpDown;
       private: System::Windows::Forms::Label^  label;
       private: System::Windows::Forms::TableLayoutPanel^  tableLayoutPanel1;
       private: System::ComponentModel::Container ^components;
       #pragma region Windows Form Designer generated code
       void InitializeComponent(void);
    };
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>   CustomCodeDomSerializer
    /// This is a specialized usercontrol designed to incapsulate another usercontrol (in this case a  
    /// NumericUpDownToolStripItem.  In order to use this class, you must copy this entire class and 
    /// create a new object.  (You can do this right underneath your usercontrol in the same file 
    /// if you wish.  You must specifiy the type of your object every place its mentioned.
    ///   
    /// To Note:  The toolbox bitmap is what the icon will look like.  You can specify any old control.
    /// It is possible to use a custom icon, but I can't figure out how.
    ///</summary>
    /// 
    /// <value> The tool strip control host. </value>
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    
    [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability::All),
     ToolboxBitmap(::NumericUpDown::typeid)]
    public ref class NumericUpDownToolStripItem : ToolStripControlHost
    {
       //replace this type
       private: LabeledNumericUpDown ^_Control;
    
       public: [Category("Object Host"), Description(L"Hosted usercontrol object"), 
        DisplayName("UserControl Object"), Browsable(true), NotifyParentProperty(true),
        DesignerSerializationVisibility(DesignerSerializationVisibility::Content)]
        //replace this properties type
       property LabeledNumericUpDown ^UserControlObject
       {
         //replace this properties return type
         LabeledNumericUpDown ^get() { return this->_Control; }
       } 
    
       public: NumericUpDownToolStripItem(void) : 
          System::Windows::Forms::ToolStripControlHost(gcnew FlowLayoutPanel())
       { 
          //replace this constructor type
          _Control = gcnew LabeledNumericUpDown();
    
          //don't touch this
          FlowLayoutPanel ^thePanel = (FlowLayoutPanel ^)this->Control;
          thePanel->BackColor = Color::Transparent;
          thePanel->Controls->Add(_Control);
       }   
    };