C# 如何创建用于在WinForms中显示其他用户控件集合的用户控件?

C# 如何创建用于在WinForms中显示其他用户控件集合的用户控件?,c#,winforms,user-controls,C#,Winforms,User Controls,我需要创建一个用户控件MyTypeListControl,以使用每个对象的用户控件MyTypeDisplayControl实例显示类型为MyType的对象集合 这样我就可以 将MyTypeListControl的实例添加到我的WinForm中,然后 加载MyType和 将其分配给MyTypeListControl的数据源 在结果中,它应该在MyTypeListControl的实例中生成并显示适当的MyTypeDisplayControl实例计数 如果我需要显示属性列表,那么等价物将是DataGr

我需要创建一个用户控件
MyTypeListControl
,以使用每个对象的用户控件
MyTypeDisplayControl
实例显示类型为
MyType
的对象集合

这样我就可以

  • 将MyTypeListControl的实例添加到我的WinForm中,然后
  • 加载
    MyType
  • 将其分配给MyTypeListControl的数据源
  • 在结果中,它应该在
    MyTypeListControl
    的实例中生成并显示适当的
    MyTypeDisplayControl
    实例计数

    如果我需要显示属性列表,那么等价物将是
    DataGrid
    ,其中
    MyType
    中的特定字段分配给特定的
    DataGrid
    列,但我想将每个
    MyType
    项视为一个用户控件,它在可视化表示和功能方面比
    DataGrid
    为其行提供的功能更强大

    这可能吗

    如何创建我的收集类型,但这只是问题解决方案的一小部分…

    这非常简单(如果您知道如何创建),并且不需要像您一开始所想的那样花费太多精力(至少对于处理少于100项的收集的简单实现是如此)

    因此,首先让我们创建一个MyType:

    public class MyType
    {
        public static MyType Empty = new MyType(String.Empty, DateTime.MinValue);
    
        public MyType(string myName, DateTime myBirthday)
        {
            MyName = myName;
            MyBirthday = myBirthday;
        }
    
        public DateTime MyBirthday { get; private set; }
    
        public string MyName { get; private set; }
    }
    
    接下来,我们需要一个MyTypeControl:

    public partial class MyTypeControl : UserControl
    {
        private MyType _MyType;
        private Label labelBirthday;
        private Label labelName;
        private Label labelSeparator;
    
        public MyTypeControl()
        {
            InitializeComponent();
        }
    
        public event EventHandler MyTypeChanged;
    
        public MyType MyType
        {
            get { return _MyType; }
            set
            {
                if (_MyType == value)
                    return;
    
                _MyType = value ?? MyType.Empty;
                OnMyTypeChanged(EventArgs.Empty);
            }
        }
    
        protected virtual void OnMyTypeChanged(EventArgs eventArgs)
        {
            UpdateVisualization();
            RaiseEvent(MyTypeChanged, eventArgs);
        }
    
        protected void UpdateVisualization()
        {
            SuspendLayout();
    
            labelName.Text = _MyType.MyName;
            labelBirthday.Text = _MyType.MyBirthday.ToString("F");
            labelBirthday.Visible = _MyType.MyBirthday != DateTime.MinValue;
    
            ResumeLayout();
        }
    
        private void InitializeComponent()
        {
            labelName = new Label();
            labelBirthday = new Label();
            labelSeparator = new Label();
            SuspendLayout();
            labelName.Dock = DockStyle.Top;
            labelName.Location = new Point(0, 0);
            labelName.TextAlign = ContentAlignment.MiddleCenter;
            labelBirthday.Dock = DockStyle.Top;
            labelBirthday.TextAlign = ContentAlignment.MiddleCenter;
            labelSeparator.BorderStyle = BorderStyle.Fixed3D;
            labelSeparator.Dock = DockStyle.Top;
            labelSeparator.Size = new Size(150, 2);
            Controls.Add(labelSeparator);
            Controls.Add(labelBirthday);
            Controls.Add(labelName);
            MinimumSize = new Size(0, 48);
            Name = "MyTypeControl";
            Size = new Size(150, 48);
            ResumeLayout(false);
        }
    
        private void RaiseEvent(EventHandler eventHandler, EventArgs eventArgs)
        {
            var temp = eventHandler;
    
            if (temp != null)
                temp(this, eventArgs);
        }
    }
    
    然后是我们神奇的列表控件:

    public class MyTypeListControl : UserControl
    {
        private ObservableCollection<MyType> _Items;
    
        public MyTypeListControl()
        {
            AutoScroll = true;
            _Items = new ObservableCollection<MyType>();
            _Items.CollectionChanged += OnItemsCollectionChanged;
        }
    
        public Collection<MyType> Items
        {
            get { return _Items; }
        }
    
        private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            UpdateVisualization();
        }
    
        private void UpdateVisualization()
        {
            SuspendLayout();
            Controls.Clear();
    
            foreach (var item in _Items)
            {
                var control = new MyTypeControl { MyType = item, Dock = DockStyle.Top };
                Controls.Add(control);
                Controls.SetChildIndex(control, 0);
            }
    
            ResumeLayout();
        }
    }
    

    为什么不使用FlowLayoutPanel?除非我误解了你的问题,否则你可以通过将用户控件的列表添加到FlowLayoutPanel来显示它们,并且你也可以轻松地操作集合。@JoshL。我是否可以向FlowLayoutPanel添加控件集合,类似于DataGrid.DataSource=ICollection?你的意思是使用控件集合进行操纵吗?@downvorters-这个问题有什么问题吗?如果你能说明出了什么问题,我会有所改进,这会很有帮助;)@JoshL谢谢,如果helpsFlowLayoutPanel没有类似DataGrid.DataSource的东西,我会看一看,这将是您必须自己实现的东西(或者您可以在UserControl的模型中实现InotifyProperty更改)。谢谢,这看起来很有希望-我将在检查此解决方案时发表评论是的,这是预期的工作!我仍然不明白为什么这个问题得到如此负面的评价,但主要是我得到了一个好答案!如果您不介意的话,我将添加一个小的更新,这样解决方案就可以接受MyType-s的集合
    myTypeListControl.Items.Add(new MyType("Adam", DateTime.UtcNow.Add(-TimeSpan.FromDays(365 * 40))));
    myTypeListControl.Items.Add(new MyType("Eva", DateTime.UtcNow.Add(-TimeSpan.FromDays(365 * 38))));