他のビジュアルコントロールを管理する非ビジュアルコンポーネントがあります。
コンポーネントが動作しているフォームへの参照が必要ですが、それを取得する方法がわかりません。
コンポーネントをデザイナーにドロップするだけで機能するようにしたいので、親をコントロールとして指定してコンストラクターを追加するかどうかはわかりません。
私が持っていたもう一つの考えは、コントロールとして親のプロパティを持ち、デフォルト値を「Me」とすることでした
どんな提案も素晴らしいでしょう
編集:
明確にするために、これはcontrolではなくcomponentです、ここを参照してください: ComponentModel.Component
[以下のISite手法は設計時にのみ機能することを理解することが重要です。 ContainerControlはパブリックであり、値が割り当てられるため、VisualStudioは実行時にそれを設定する初期化コードを書き込みます。サイトは実行時に設定されますが、そこからContainerControlを取得できません]
ここに記事があります 非ビジュアルコンポーネントに対してそれを行う方法を説明します。
基本的には、コンポーネントContainerControlをコンポーネントに追加する必要があります。
public ContainerControl ContainerControl
{
get { return _containerControl; }
set { _containerControl = value; }
}
private ContainerControl _containerControl = null;
そして、Siteプロパティをオーバーライドします。
public override ISite Site
{
get { return base.Site; }
set
{
base.Site = value;
if (value == null)
{
return;
}
IDesignerHost Host = value.GetService(
typeof(IDesignerHost)) as IDesignerHost;
if (Host != null)
{
IComponent componentHost = Host.RootComponent;
if (componentHost is ContainerControl)
{
ContainerControl = componentHost as ContainerControl;
}
}
}
}
これを行うと、ContainerControlが初期化されて、デザイナーが含まれているフォームを参照します。リンクされた記事はそれをより詳細に説明しています。
方法を確認する良い方法は、Lutz Reflectorなどのツールで必要な動作と同様の動作をする.NET Frameworkのタイプの実装を確認することです。この場合、System.Windows.Forms.ErrorProviderはその良い例です。含まれているフォームを知る必要があるコンポーネントです。
再帰呼び出しを使用して、コントロールチェーンを調べます。これをコントロールに追加します。
public Form ParentForm
{
get { return GetParentForm( this.Parent ); }
}
private Form GetParentForm( Control parent )
{
Form form = parent as Form;
if ( form != null )
{
return form;
}
if ( parent != null )
{
// Walk up the control hierarchy
return GetParentForm( parent.Parent );
}
return null; // Control is not on a Form
}
編集:これを入力していたときに、質問が変更されたようです。コンポーネントの場合、そのコンポーネントのコンストラクターはその親をパラメーターとして受け取り、親は構築時にこれを渡す必要があります。タイマーなど、他のいくつかのコンポーネントがこれを行います。
親コントロールをメンバーとして保存し、上記の代わりに、上記のParentFormプロパティで使用します。
何らかの方法で親コンテナを設定する必要があります。コンポーネントは単なるクラスであり、他のすべてと同じようにメモリに常駐します。何かがそれを作ったとあなたに言わない限り、それはそれを作ったものの真の文脈を持っていません。親コントロールプロパティを作成して設定します。
または、単にコントロールから派生してFindForm()を使用します。すべてのコントロールに可視コンポーネントが必要なわけではありません
私は this solution を見つけました。これは入力を必要としません。 C#の場合、次のように実装しました。
public partial class RegistryManager : Component, ISupportInitialize
{
private Form _parentForm;
public Form ParentForm
{
get { return _parentForm; }
set { _parentForm = value; }
}
// Etc....
#region ISupportInitialize
public void BeginInit() { }
public void EndInit()
{
setUpParentForm();
}
private void setUpParentForm()
{
if (_parentForm != null) return; // do nothing if it is set
IDesignerHost Host;
if (Site != null)
{
Host = Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (Host != null)
{
if (Host.RootComponent is Form)
{
_parentForm = (Form)Host.RootComponent;
}
}
}
}
#endregion
}
この方法では、ユーザーがParentFormを設定できますが、親フォームによってデフォルトとして設定されます。
お役に立てば幸いです。
コンポーネントが他のビジュアルコントロールを管理している場合、それらを介して親にアクセスできるはずです。
これを試して ....
_private Form GetParentForm(Control parent)
{
if (parent is Form)
return parent as Form;
return parent.FindForm();
}
_
コンポーネントからGetParentForm(this.Parent)
を呼び出す
IComponentのSiteプロパティを使用したいと思います。これは、多かれ少なかれParentプロパティと同等です。
ありがとうロブ、私はVB.Netプログラムであなたの解決策を使いました、これは次のようになります:
''' <summary>
''' Returns the parent System.Windows.form of the control
''' </summary>
''' <param name="parent"></param>
''' <returns>First parent form or null if no parent found</returns>
''' <remarks></remarks>
Public Shared Function GetParentForm(ByVal parent As Control) As Form
Dim form As Form = TryCast(parent, Form)
If form IsNot Nothing Then
Return form
End If
If parent IsNot Nothing Then
' Walk up the control hierarchy
Return GetParentForm(parent.Parent)
End If
' Control is not on a Form
Return Nothing
End Function
私のブログでそれを参照しました: http://www.dailycode.info/Blog/post/2012/07/03/How-to-get-a-user-controls-parent-form-(Windows-forms ).aspx