- PR -

子コンポーネントが削除されない

1
投稿者投稿内容
sou
ベテラン
会議室デビュー日: 2002/09/25
投稿数: 56
投稿日時: 2006-11-10 19:11
System.Windows.Forms.Panel コントロールを継承して独自のコントロール(ParentPanel)を作成しています。
このコントロールは複数個の子コンポーネント(ChildComponent)をコレクション(ChildComponentCollection)として保持しています。

下記のようなコードで、ParentPanelのChildComponentCollectionに、VS2005のデザイナ画面よりChildComponentが追加されるようになりました。(VS2005の自動生成コードにもコードが記述される)

質問したいことは、デザイナ画面に貼り付けたParentPanelをデザイナ画面で削除した場合に、ChildComponentCollectionに追加されたChildComponentを同時に削除する方法を知りたいんです。

下記のコードではParentPanelを生成するコードは削除されるのですが、ChildComponentに関するコードは削除されずにごみのように残ってしまいます。

現在、ChildComponentはComponentクラスを継承して作成していますが、これを例えばPanelクラスより継承して作成すると、ParentPanelが削除されると同時にChildComponentも削除されるようになります。
どうやらデザイナが追加されたComponentを親コントロールの子コンポーネントとして認識していないのかなと?考えています。どうやったら認識させることができるのでしょうか?

コード:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace TestApp
{
    [Serializable]
    [Designer(typeof(ParentPanel.ParentPanelDesigner))]
    public class ParentPanel : Panel
    {
        internal sealed class ParentPanelDesigner : System.Windows.Forms.Design.ParentControlDesigner
        {
            public override ICollection AssociatedComponents
            {
                get
                {

                    return ((ParentPanel)base.Control).ChildComponents;
                }
            }
        }

        public ParentPanel()
        {
            this.childComponents = new ChildComponentCollection(this);
        }

        private ChildComponentCollection childComponents;
        
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ChildComponentCollection ChildComponents
        {
            get { return childComponents; }
        }

    }
    [Serializable]
    public class ChildComponentCollection : CollectionBase
    {
        private ParentPanel parent;

        public ChildComponentCollection(ParentPanel p)
        {
            parent = p;
        }

        public ChildComponent this[int index]
        {
            get
            {
                return ((ChildComponent)List[index]);
            }
            set
            {
                List[index] = value;
            }
        }

        public int Add(ChildComponent value)
        {
            return (List.Add(value));
        }

        public int IndexOf(ChildComponent value)
        {
            return (List.IndexOf(value));
        }

        public void Insert(int index, ChildComponent value)
        {
            List.Insert(index, value);
        }

        public void Remove(ChildComponent value)
        {
            List.Remove(value);
        }

        public bool Contains(ChildComponent value)
        {
            return (List.Contains(value));
        }

        protected override void OnInsertComplete(int index, Object value)
        {
            ChildComponent item = (ChildComponent)value;
            item.Parent = parent;
        }
    }

    [Serializable]
    [Designer(typeof(ChildComponent.ChildComponentDesigner))]
    [DesignTimeVisibleAttribute(true)]
    public class ChildComponent : Component
    {
        internal sealed class ChildComponentDesigner : System.ComponentModel.Design.ComponentDesigner
        {
        }

        public ChildComponent()
        {
        }

        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        private ParentPanel parent;

        public ParentPanel Parent
        {
            get { return parent; }
            internal set { parent = value; }
        }

    }

}


sou
ベテラン
会議室デビュー日: 2002/09/25
投稿数: 56
投稿日時: 2006-11-11 02:11
解決しました。

IDesignerHost.DestroyComponent(IComponent)メソッドで子コンポーネント(ChildComponent)を破棄することにより、デザイナから削除されました。

以下に修正したコードと参考にしたサイトを示します。

コード:

namespace TestApp
{
[Serializable]
[Designer(typeof(ParentPanel.ParentPanelDesigner))]
public class ParentPanel : Panel
{
internal sealed class ParentPanelDesigner : System.Windows.Forms.Design.ParentControlDesigner
{

#region 修正した箇所
private IDesignerHost host = null;

public override void Initialize(IComponent component)
{
base.Initialize(component);

this.host = this.Control.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
if (this.host != null)
{
foreach (ChildComponent h in ((ParentPanel)this.Control).ChildComponents)
{
this.host.DestroyComponent(h);
}
}
}

base.Dispose(disposing);
}
#endregion


public override ICollection AssociatedComponents
{
get
{

return ((ParentPanel)base.Control).ChildComponents;
}
}
}

public ParentPanel()
{
this.childComponents = new ChildComponentCollection(this);
}


private ChildComponentCollection childComponents;

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ChildComponentCollection ChildComponents
{
get { return childComponents; }
}

}
[Serializable]
public class ChildComponentCollection : CollectionBase
{
private ParentPanel parent;

public ChildComponentCollection(ParentPanel p)
{
parent = p;
}

public ChildComponent this[int index]
{
get
{
return ((ChildComponent)List[index]);
}
set
{
List[index] = value;
}
}

public int Add(ChildComponent value)
{
return (List.Add(value));
}

public int IndexOf(ChildComponent value)
{
return (List.IndexOf(value));
}

public void Insert(int index, ChildComponent value)
{
List.Insert(index, value);
}

public void Remove(ChildComponent value)
{
List.Remove(value);
}

public bool Contains(ChildComponent value)
{
return (List.Contains(value));
}

protected override void OnInsertComplete(int index, Object value)
{
ChildComponent item = (ChildComponent)value;
item.Parent = parent;
}
}

[Serializable]
[Designer(typeof(ChildComponent.ChildComponentDesigner))]
[DesignTimeVisibleAttribute(true)]
public class ChildComponent : Component
{
internal sealed class ChildComponentDesigner : System.ComponentModel.Design.ComponentDesigner
{
}

public ChildComponent():base()
{
}

private string name;

public string Name
{
get { return name; }
set { name = value; }
}

private ParentPanel parent;

public ParentPanel Parent
{
get { return parent; }
internal set { parent = value; }
}

}
}



参考にしたサイト
方法 : デザイン時サービスにアクセスする
http://msdn2.microsoft.com/ja-jp/library/ms171822(VS.80).aspx

[ メッセージ編集済み 編集者: sou 編集日時 2006-11-11 02:13 ]
1

スキルアップ/キャリアアップ(JOB@IT)