6

カスタム コントロールを作成しました。「タブ」というプロパティがあります。このプロパティは、「DockContainerItem」クラスから継承された「FloorsInformation」コントロールのコレクションをカスタム コントロールに追加します。

カスタム コントロールのプロパティ

ここで、タブ「CollectionEditor」ウィンドウの「OK」ボタンをクリックした後、「FloorsInformation」コントロールをカスタム コントロールに追加したいと考えています。

それを行うための「AddTabs」メソッドがあります。しかし、私はそれを適切な場所で呼び出すことはできません。「Tab」プロパティの「set accessor」で「AddTabs」メソッドを呼び出さなければなりませんが、それは起こりません。

「Tab」プロパティの「get アクセサ」からこのメソッドを呼び出すこともできますが、「Tab」プロパティの「get アクセサ」でこのメソッドを呼び出すとエラーになります。 「タブ」プロパティを継続的に。

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

ちなみに、このメソッドは CollectionEditor クラスを継承した ItemsCollectionEditor クラスの SetItems オーバーライド メソッドで呼び出すことができます。それでも、カスタム コントロール クラスの新しいインスタンスを作成しないと、"AddTabs" メソッドにアクセスできません。カスタム コントロールの新しいインスタンスを作成すると、「AddTabs」メソッドは、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);
    }
}

目標を達成するために何をしなければなりませんか?

4

1 に答える 1

1

いくつかのオプションがあります。

オプション1:

FloorsGrouping.Items設計時にプロパティを公開したいだけの場合は、Tabプロパティのタイプをに変更して、プロパティSubItemsCollectionを返すことができItemsます。この場合、コレクション変更イベントのインターセプトについて心配する必要はありません。自動的に発生します。

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

オプション2:

コレクション変更イベントをインターセプトする必要がある場合は、を実装Tabsするから継承するようにクラスを変更します。ObservableCollection<FloorsInformation>INotifyCollectionChanged

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

そして、FloorsGroupingコンストラクターで、CollectionChangedイベントをサブスクライブします。

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

最後に、イベントハンドラーで、コレクションの変更を処理します。

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

オプション2で気付くのはCollectionChanged、特に[OK]ボタンがクリックされたときではなく、コレクションエディターでの編集によってイベントがリアルタイムで発生することです。ただし、ユーザーが最終的にコレクションエディタの[OK]または[キャンセル]ボタンをクリックすると、コレクションの状態は正確になります。

于 2012-11-25T02:51:54.407 に答える