简体   繁体   中英

How do I add controls to my UserControl when I edit its Collection of controls?

I am using C# in Windows Forms to create a UserControl . It's my first .NET UserControl , but I have created many custom components in Delphi in the past, so it's not a totally unfamiliar concept.

My new control is a Timeline, similar to those seen in video editing software in which you can place video and audio on various channels. My control can also contain a number of channels. I have created a control to act as the basic Timeline, and another control which becomes the Channel when added to the Timeline. I have created a Collection of Channel objects as a property of the Timeline, and in design mode it gives me a collection editor so that I can add, modify and delete Channels. I've made the Channel object Serializeable , and the collection of Channels I create persists in the form on which I have placed the Timeline.

What I would like to be able to do is when I exit the Collection editor, the Timeline is updated to display the Channel objects. At present, they exist in the Timeline, but are not being displayed within the Timeline. Obviously, they have to be added to the Controls collection of the Timeline object, but I am at a loss to work out where I should do this. Is there some kind of event raised that says that the Collection has changed, so that I can then go and add or remove the Channels from the displayed Timeline?

Here's my code for the Timeline control:

using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.ComponentModel.Design;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace CMSTimeline
{
    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
    public partial class CMSTimeline : UserControl
    {
        // The collection of Channels
        private Collection<TimelineChannel> channels = new Collection<TimelineChannel>();

        public CMSTimeline()
        {
            InitializeComponent();
        }

        // The property that exposes the collection of channels to the object inspector
        [Category("Data")]
        [Description("The Timeline channels")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Collection<TimelineChannel> Channels
        {
            get { return channels; }
            set { channels = value; }
        }
    }

    class CMSTimelineDesigner : ControlDesigner
    {
        public override void Initialize(IComponent component)
        {
            base.Initialize(component);
            CMSTimeline uc = component as CMSTimeline;
        }
    }
}

And here is the Channel object code.

using System;
using System.Windows.Forms;

namespace CMSTimeline
{
    [Serializable]
    public partial class TimelineChannel : UserControl
    {
        public TimelineChannel()
        {
            InitializeComponent();
            UICaption.Text = "Channel";
        }

        public TimelineChannel(string aCaption)
        {
            InitializeComponent();
            UICaption.Text = aCaption;
        }

        public string Caption
        {
            get
            {
                return UICaption.Text;
            }
            set
            {
                UICaption.Text = value;
            }
        }
    }
}

Everything else works just fine. My Timeline control appears in the Toolbox, and I can drop it on my form.

When I select the Timeline, its properties are shown, including the Channels property, which appears as a Collection as expected. Pressing the [...] button opens a default collection editor (which I might change later), and I can Add and Delete Channels as required. When I close the editor, the Channels exist (I can see the min the form's Designer.cs file), but I want them to appear in the Timeline object.

So how should I get them added to the Timeline's Controls?

Instead of Collection<TimelineChannel> use ObservableCollection<TimeLineChannel> and add handler to it like this

myObservable.CollectionChanged += (sender, e) =>
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        foreach (TimeLineChannel c in e.NewItems)
        {
            TimeLine.Controls.Add(c);
        }
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM