2012-11-21 15 views
6

Ho creato il controllo personalizzato. Ha una proprietà che si chiama "Tab". Questa proprietà aggiunge una raccolta di controlli "FloorsInformation" ereditati dalla classe "DockContainerItem" al mio controllo personalizzato.Aggiungere controlli secondari al controllo personalizzato dopo aver fatto clic sul pulsante "OK" della finestra "CollectionEditor" in fase di progettazione

My custom control properties

Ora, voglio aggiungere controlli "FloorsInformation" al mio controllo personalizzato dopo fare clic sul pulsante "OK" della finestra Tab "CollectionEditor".

"Tabs Collection Editor" window

devo metodo "AddTabs" per farlo. Tuttavia, non posso chiamarlo nel posto giusto. Devo chiamare il metodo "AddTabs" in "set accessor" della proprietà "Tab", ma non si verifica mai.

Posso anche chiamare questo metodo da "get accessor" della proprietà "Tab", ma chiamare questo metodo in "get accessor" della proprietà "Tab" causerà un errore, perché l'accesso al programma al " ottenere accessor "della proprietà" Tab "continuamente.

[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))] 
[ToolboxItem(true), ToolboxBitmap(typeof(ToolboxIconResourceFinder), "FloorsGrouping.bmp")] 
[DisplayName("Floors Group")] 
[Editor("WindowsFormsControlLibrary2.FloorsGrouping, WindowsFormsControlLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=197889249da45bfc", typeof(UITypeEditor))] 
[Description("Floorssssssss")] 
[Category("Saino")] 
[DefaultProperty("Text")] 
[DesignerCategory("Component")] //Form //Designer //Empty String ("") 
public partial class FloorsGrouping : Bar 
{ 
    private Tabs tabs = new Tabs(); 

    public FloorsGrouping() 
    { 
     InitializeComponent(); 
     this.AutoHide = true; 
    } 

    [Category("Data")] 
    [DisplayName("Tabs")] 
    [Description("Tabsssssssssssss")] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
    [Editor(typeof(ItemsCollectionEditor), typeof(UITypeEditor))] 
    public Tabs Tab 
    { 
     get 
     { 
      //AddTabs(); 
      return tabs; 
     } 
     //set 
     //{ 
      //AddTabs(); 
     //} 
    } 

    public void AddTabs() 
    { 
     foreach (DockContainerItem dciItem in Tab) 
     { 
      if (!Parent.Controls.ContainsKey(dciItem.Name)) 
      { 
       Items.Add(dciItem); 
      } 
     } 
    } 
} 

[DisplayName("Floors Information")] 
[Description("Floors Informationnnnnnnnnnnnnnnn")] 
[DefaultProperty("Text")] 
[DesignerCategory("Component")] 
[ToolboxItem(false)] 
public class FloorsInformation : DockContainerItem 
{ 
    /// <summary> 
    /// Required designer variable. 
    /// </summary> 
    private System.ComponentModel.IContainer components = null; 

    private SimilarFloorsInformation similarFloorsInformation = new SimilarFloorsInformation(); 
    private AllFloorsInformation allFloorsInformation = new AllFloorsInformation(); 
    private string text = "Floors Information"; 

    public FloorsInformation() 
    { 

    } 

    [Category("Data")] 
    [DisplayName("Similar Floors Panel")] 
    [Description("Similar Floors Panellllllllllllllllllll")] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
    public SimilarFloorsInformation SimilarFloorsInfo 
    { 
     get 
     { 
      return similarFloorsInformation; 
     } 
     set 
     { 
      similarFloorsInformation = value; 
     } 
    } 

    [Category("Data")] 
    [DisplayName("All Floors Group")] 
    [Description("All Floors Groupppppppppppppp")] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
    public AllFloorsInformation AllFloorsInfo 
    { 
     get 
     { 
      return allFloorsInformation; 
     } 
     set 
     { 
      allFloorsInformation = value; 
     } 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 
} 

public class Tabs : CollectionBase 
{ 
    public FloorsInformation this[int intIndex] 
    { 
     get 
     { 
      return (FloorsInformation)InnerList[intIndex]; 
     } 
     set 
     { 
      InnerList[intIndex] = value; 
     } 
    } 

    public int Add(FloorsInformation finfItemType) 
    { 
     return InnerList.Add(finfItemType); 
    } 

    public bool Contains(FloorsInformation finfItemType) 
    { 
     return InnerList.Contains(finfItemType); 
    } 

    public void Remove(FloorsInformation finfItemType) 
    { 
     InnerList.Remove(finfItemType); 
    } 

    public void Insert(int intIndex, FloorsInformation finfItemType) 
    { 
     InnerList.Insert(intIndex, finfItemType); 
    } 

    public FloorsInformation[] GetValues() 
    { 
     FloorsInformation[] finfItemType = new FloorsInformation[InnerList.Count]; 
     InnerList.CopyTo(0, finfItemType, 0, InnerList.Count); 
     return finfItemType; 
    } 
} 

A proposito, posso chiamare questo metodo in "setItems" Metodo overrode della classe "ItemsCollectionEditor" che viene ereditato dalla classe "CollectionEditor"; tuttavia, non posso accedere al metodo "AddTabs" senza creare una nuova istanza della mia classe di controllo personalizzata. Se creo una nuova istanza del mio controllo personalizzato, il metodo "AddTabs" applica le modifiche su un nuovo controllo del mio controllo personalizzato e non sul controllo personalizzato aggiunto corrente nel WinForm.

public class ItemsCollectionEditor : CollectionEditor 
{ 
    private Type[] typItems; 

    public ItemsCollectionEditor(Type typItem) 
     : base(typItem) 
    { 
     typItems = new Type[] { typeof(FloorsInformation) }; 
    } 

    protected override Type[] CreateNewItemTypes() 
    { 
     return typItems; 
    } 

    protected override CollectionForm CreateCollectionForm() 
    { 
     CollectionForm collectionForm = base.CreateCollectionForm(); 
     collectionForm.Text = "Tabs Collection Editor"; 
     return collectionForm; 
     //return base.CreateCollectionForm(); 
    } 

    protected override object SetItems(object editValue, object[] value) 
    { 
     return base.SetItems(editValue, value); 
    } 
} 

Cosa devo fare per raggiungere il mio obiettivo?

risposta

1

Hai un paio di opzioni.

Opzione 1:

Se siete semplicemente desideroso di esporre la proprietà FloorsGrouping.Items in fase di progettazione, è possibile modificare il tipo della proprietà Tab-SubItemsCollection e restituire la proprietà Items. In questo caso, non dovrai preoccuparti di intercettare gli eventi di modifica della raccolta, ma avverrà automaticamente.

[Category("Data")] 
[DisplayName("Tabs")] 
[Description("Tabsssssssssssss")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
[Editor(typeof(ItemsCollectionEditor), typeof(UITypeEditor))] 
public SubItemsCollection Tab { 
    get { 
     return Items; 
    } 
} 

Opzione 2:

Se si ha bisogno di intercettare gli eventi di modifica di raccolta, modificare la classe Tabs di ereditare da ObservableCollection<FloorsInformation>, che implementa INotifyCollectionChanged.

public class Tabs : System.Collections.ObjectModel.ObservableCollection<FloorsInformation> { 
} 

E nel vostro FloorsGrouping costruttore, sottoscrivere l'evento CollectionChanged.

public FloorsGrouping() { 
    ... 
    tabs.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(tabs_CollectionChanged); 
} 

Infine, nel gestore di eventi, elaborare la modifica della raccolta.

private void tabs_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { 
    switch (e.Action) { 
     case System.Collections.Specialized.NotifyCollectionChangedAction.Add: 
      foreach (DockContainerItem dciItem in e.NewItems) { 
       if (!Parent.Controls.ContainsKey(dciItem.Name)) 
        Items.Add(dciItem); 
      } 
      break; 
     case System.Collections.Specialized.NotifyCollectionChangedAction.Reset: 
      Items.Clear(); 
      break; 
    } 
} 

cosa che noterete con l'opzione 2 è che i CollectionChanged generato l'evento in tempo reale con la modifica nell'editor di raccolta, non specificamente quando il pulsante OK viene cliccato.Tuttavia, quando l'utente fa clic sul pulsante OK o Annulla nell'editor della raccolta, lo stato della raccolta è accurato.