2012-11-21 24 views
6

Stworzyłem niestandardową kontrolę. Ma właściwość o nazwie "Tab". Ta właściwość dodaje do zestawu kontrolek "FloorsInformation" dziedziczonych z klasy "DockContainerItem".Dodaj kontrole podrzędne do niestandardowego sterowania po kliknięciu przycisku "OK" w oknie "CollectionEditor" w czasie projektowania

My custom control properties

Teraz chcę dodać sterowanie „FloorsInformation” do mojego niestandardowego kontroli po kliknięciu przycisku „OK” w oknie zakładki „CollectionEditor”.

"Tabs Collection Editor" window

mam "AddTabs" sposób to robić. Nie mogę jednak nazwać tego we właściwym miejscu. Muszę nazwać metodę "AddTabs" w "ustawionym akcesorium" właściwości "Tab", ale nigdy nie występuje.

Mogę również wywołać tę metodę z "get accessor" właściwości "Tab", ale wywołanie tej metody w "get accessor" właściwości "Tab" spowoduje błąd, ponieważ dostęp do programu " uzyskać ciąg "accessor" właściwości "Tab".

[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; 
    } 
} 

Nawiasem mówiąc, mogę wywołać tę metodę w „SetItems” metody overrode klasy „ItemsCollectionEditor”, które jest dziedziczone z klasy „CollectionEditor”; nie mogę jednak uzyskać dostępu do metody "AddTabs" bez tworzenia nowej instancji mojej niestandardowej klasy kontrolnej. Jeśli utworzę nową instancję kontrolki niestandardowej, metoda "AddTabs" stosuje zmiany na nowym sterowaniu kontrolką niestandardową, a nie na aktualnie dodanym sterowaniu niestandardowym w 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); 
    } 
} 

Co muszę zrobić, aby osiągnąć mój cel?

Odpowiedz

1

Masz kilka opcji.

Wariant 1:

Jeśli dopiero chcąc narażać właściwości w czasie projektowania FloorsGrouping.Items, można zmienić rodzaj tej posiadłości Tab do SubItemsCollection i zwrotu mienia Items. W takim przypadku nie musisz się martwić przechwytywaniem żadnych zdarzeń związanych ze zmianą kolekcji, stanie się to automatycznie.

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

Opcja 2:

Jeśli potrzebują przechwytywać zdarzenia zmiany kolekcji, należy zmodyfikować klasę Tabs do dziedziczenia z ObservableCollection<FloorsInformation>, który realizuje INotifyCollectionChanged.

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

A w konstruktorze FloorsGrouping, zapisz się na razie CollectionChanged.

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

Wreszcie, w programie obsługi zdarzeń, przetwarzaj zmianę kolekcji.

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; 
    } 
} 

Co można zauważyć z opcji 2 jest to, że Zdarzenie CollectionChanged w czasie rzeczywistym edycji w edytorze zbiórki nie specjalnie po naciśnięciu przycisku OK zostanie kliknięty.Jednak, gdy użytkownik ostatecznie kliknie przycisk OK lub Anuluj w edytorze kolekcji, stan kolekcji jest poprawny.