【问题标题】:Visual Studio fires an error when I drag my user control onto the design view当我将用户控件拖到设计视图上时,Visual Studio 触发错误
【发布时间】:2010-11-29 13:38:58
【问题描述】:

我有两个用户控件,一个是一个带有复选框的简单图片支架。另一个充当容器而不是具有先前控件的集合。

所以一个Horizo​​ntalPictureScroller可以有很多SelectablePicture控件。我将为每个控件粘贴小代码:

首先,Horizo​​ntalPictureScroller

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.ObjectModel;

namespace WinformsPlayground
{
    [Serializable()]
    public partial class HorizontalPictureScroller : UserControl
    {
        public HorizontalPictureScroller()
        {
            InitializeComponent();
            Pictures = new ObservableCollection<SelectablePicture>();
            Pictures.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Pictures_CollectionChanged);
        }       

        #region "Properties"
        public ObservableCollection<SelectablePicture> Pictures { get; set; }
        private int PositionControlX = 0;
        #endregion

        #region "Methods"
        private void RedrawPictures()
        {
            PositionControlX = 0;

            foreach (var picture in Pictures)
            {
                picture.Location = new Point(PositionControlX + panelPicturesWrapper.AutoScrollPosition.X, 0);
                PositionControlX += 130;
                panelPicturesWrapper.Controls.Add(picture);
            }
        }

        public void AddPicture(SelectablePicture picture)
        {
            Pictures.Add(picture);
        }

        public void RemovePicture(SelectablePicture picture)
        {
            Pictures.Remove(picture);
        }

        public void MovePictureLeft(int index)
        {
            SelectablePicture tmpPicture = Pictures[index];
            Pictures[index] = Pictures[index - 1];
            Pictures[index - 1] = tmpPicture;
        }

        public void MovePictureRight(int index)
        {
            SelectablePicture tmpPicture = Pictures[index];
            Pictures[index] = Pictures[index + 1];
            Pictures[index + 1] = tmpPicture;
        }
        #endregion

        #region "Events"
        void Pictures_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            RedrawPictures();
        }        
        #endregion
    }
}

现在,SelectablePicture 控件:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WinformsPlayground
{
    [Serializable()]
    public partial class SelectablePicture : UserControl
    {
        public SelectablePicture()
        {
            InitializeComponent();
            panel1.BackgroundImageLayout = ImageLayout.Zoom;
        }

        public SelectablePicture(Image image)
        {
            panel1.BackgroundImage = image;
            panel1.BackgroundImageLayout = ImageLayout.Zoom;
        }

        #region "Properties"
        public Image Image()
        {
            return panel1.BackgroundImage;
        }

        public bool IsSelected()
        {
            return chkSelected.Checked;
        }
        #endregion

        #region "Methods"
        public void ToggleCheckBox()
        {
            chkSelected.Checked = chkSelected.Checked ? false : true;
        }

        public void VisuallySelect()
        {
            this.BackColor = Color.FromArgb(51, 153, 255);
        }

        public void VisuallyDeselect()
        {
            //If none of the controls inside the usercontrol have focus, set this control to white.
            if (!this.Focused && !this.panel1.Focused && !this.chkSelected.Focused)
            {
                this.BackColor = Color.White;
            }
        }        
        #endregion

        #region "Events"
        private void panel1_Click(object sender, EventArgs e)
        {
            VisuallySelect();
            ToggleCheckBox();
            panel1.Focus();
        }

        private void chkSelected_Click(object sender, EventArgs e)
        {
            VisuallySelect();
            ToggleCheckBox();
            chkSelected.Focus();
        }

        private void SelectablePicture_Click(object sender, EventArgs e)
        {
            VisuallySelect();
            ToggleCheckBox();
            this.Focus();
        }

        private void panel1_Leave(object sender, EventArgs e)
        {
            VisuallyDeselect();
        }

        private void chkSelected_Leave(object sender, EventArgs e)
        {
            VisuallyDeselect();
        }

        private void SelectablePicture_Leave(object sender, EventArgs e)
        {
            VisuallyDeselect();
        }
        #endregion        
    }
}

这是我在尝试将 Horizo​​ntalPictureScroller 拖到我的 Winform 设计视图时遇到的错误的屏幕截图(抱歉,我无法在此处粘贴文本):

我的用户控件非常简单,我看不出代码中出了什么问题。

也许这是我的一个公然错误。 :P 非常感谢您的宝贵时间。

【问题讨论】:

    标签: c# winforms user-controls


    【解决方案1】:

    抛出异常是因为您使用的是SerializableAttribute,但UserControl 没有。

    来自SerializableAttribute 的文档:

    如果正在序列化的对象图中的任何类型未应用 SerializableAttribute 属性,则公共语言运行时将引发 SerializationException。

    【讨论】:

    • 即使我删除了 [Serializable()] 的标题,我仍然会收到该错误。事实上,我只是添加它,因为有人说这是错误的原因:P 还有其他想法吗?谢谢!
    • @Serg,当您删除 [Serializable()] 并单独添加每个控件时,它们是否都会引发异常?如果只有HorizontalPictureScroller 抛出异常,问题可能是它使用的ObservableCollection&lt;T&gt;,因为它被标记为Serializable
    • @adrift:是的!当我将它拖到设计器视图时,只有 Horizo​​ntalPictureScroller 会触发异常。有关如何解决此问题的任何建议?
    • @Serg,我尝试了一些东西,看起来问题是ObservableCollection&lt;T&gt;Serializable,但SelectablePicture 不是,不幸的是,您不能将其标记为@ 987654332@,因为它继承自 UserControl。请注意,这并不特定于ObservableCollection&lt;T&gt;SelectablePicture;如果您将其更改为List&lt;Foo&gt;,其中Foo 不是Serializable,您会得到相同的异常。有什么方法可以改变你的设计,使ObservableCollection 是某种 Serializable 的类型?
    • @adrift:感谢您抽出宝贵时间提供帮助! :D 我使用 ObservableCollection 的原因是因为我想要一个方法在每次修改集合中的某些内容时触发。你有没有推荐的替代品?谢谢!2
    【解决方案2】:

    看来UserControl SelectablePicture 需要序列化,因为它是在一个Collection 中使用的。因此,您离具有属性 [Serializable()] 的解决方案很近。但是你最好在你的 UserControl SelectablePicture 中实现 ISerializable 接口

    public partial class SelectablePicture : UserControl, ISerializable
    {
        #region ISerializable Membres
    
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            ...
        }
    
        #endregion
    }
    

    这是解决问题的第一步。这样一来,当您拖放 UserControl 时,您就不会收到错误消息。但现在您必须管理序列化。

    如果有人知道为什么需要序列化,我很感兴趣。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多