私はC#WinFormsユーザーコントロールを作成しています。ユーザコントロールがフォームに含まれているデータを必要とする時があります。ユーザコントロールがそれを含むフォームに何らかのデータが必要であることを伝える方法を教えてください。C#User Control - オブジェクトにコントロールが必要なデータを格納する方法
ありがとうございます!
私はC#WinFormsユーザーコントロールを作成しています。ユーザコントロールがフォームに含まれているデータを必要とする時があります。ユーザコントロールがそれを含むフォームに何らかのデータが必要であることを伝える方法を教えてください。C#User Control - オブジェクトにコントロールが必要なデータを格納する方法
ありがとうございます!
UserControlで発生したイベントにフォームをサブスクライブできます。
あなたのアーキテクチャは、データイベントを購読する必要がある場所を指定します。実行時または設計時にコントロールを追加するかどうかについてもう少し詳しく知ることなく、私たちはそれに答えることはできません。それぞれのケースは少しの派生を必要とします。実行時にコントロールを追加する観点から、次のような何かができる:
// Your sample control
public class MyUserControl : Control
{
public event EventHandler<EventArgs> INeedData;
public Data Data {get; set;}
private class DoSomething()
{
if(INeedData!=null) INeedData(this,null);
}
}
...
// Your Form, in the case that the control isn't already added.
var _myUserControl = new MyUserControl();
private void Form1_Load(object sender, EventArgs e)
{
_myUserControl.INeedData += new EventHandler<EventArgs>(MyUserControl_INeedData);
this.Controls.Add(myUserControl);
}
void MyUserControl_INeedData(object sender, EventArgs e)
{
_myUserControl.Data = SomeData;
}
は私には少しあいまいなようだが、:たびに、いくつかのデータは、すべての加入者が1対多のモデルに通知できる準備ができているように、
が、それ含むWinフォームでのイベントしてください。そのようなデータを取得するコンテナのメソッドを呼び出す1対1モデルで、サブスクライブされたコントロールでイベントを作成しますか?
OP - これはオブザーバーパターンです。それはあなたが探しているものかもしれません。 –
イベントの引数が編集可能なユーザーコントロールにイベントを作成します。これらのフィールドを更新するハンドラーをそのイベントに添付させます。 OnEventメソッドのこれらのフィールドを使用します。
[テストなし] 例:
public delegate void NeedsUserDataEventHandler(object sender, NeedsUserDataEventArgs args);
public class NeedsUserDataEventArgs : EventArgs
{
public UserData UserData { get; set; }
}
// In Control
public event NeedsUserDataEventHandler NeedsUserData;
public void OnNeedsUserData(NeedsUserDataEventArgs args)
{
NeedsUserDataEventHandler handler = NeedsUserData;
if (handler != null) handler(this, args);
// store your data somewhere here
}
// In Form
public override void OnLoad(object sender, EventArgs args)
{
control.NeedsUserData += ControlNeedsUserData;
}
public override void OnClosed(object sender, EventArgs args)
{
control.NeedsUserData -= ControlNeedsUserData;
}
public void ControlNeedsUserData (object sender, NeedsUserDataEventArgs args)
{
args.UserData = // set whatever here
}
それから別のコントロールが来たら、あなたはあなたのオブジェクトに戻って別のハンドラを登録する必要があるデータを必要とします。...バー...データの登録者を気にする人を作りましょう。 –
これは、データをUserControlにプッシュする必要があるかどうかによって異なります。 UserControl内のデータを移動する必要があるイベントがフォーム上で発生していますか?もしそうなら...その時点であなたのインスタンスをつかんで、パブリックプロパティを介してUserControlにデータをプッシュしてください。
このイベントが使用されていない場合、または何らかの方法でフォーム、または他のような、フォーム上のeventを露出させる「データを受信する」場合...
public event DataHandler ReceivedData;
... UserControlまたは他のコンテナがイベントに登録し、カスタムイベントargsを介してデータを受け取ることを許可します。 Formがデータのイニシエータであるため、UserControlにイベントをプッシュし、UserControlにラッチするように強制します。
イベントをフォームに入れ、ユーザーコントロールをそれに添付させると、クリーンアップの順序が混乱するため、危険です。どちらも処分できない循環参照で簡単に終わることができます。この種のメモリリークをデバッグするのは非常に困難です。 – pdr
@ pdrそれは間違っているので混乱していますか?うーん...このフォーム(これはどんなオブジェクトでもよい)はデータの背後にあるオブジェクトです。他のオブジェクトがこのフォームからのデータを必要とする場合、イベントに登録してデータを受け取る能力も必要です。彼がデータを上げるときにフォームを強制的に各オブジェクトにラッチすることはメリットがありません。 –
私はアプローチが「間違っている」と言っているわけではありませんが、危険であると言います。しかし、あなたの答えの最後の文は間違っています。 – pdr
ユーザーコントロールにカスタムイベントを作成し、その中にフォームのフックを持っています。カスタムイベント引数が必要な場合は、それらも作成できます。ユーザーコントロールで
:あなたのイベントが公開されているので、あなたにも、あなたのコントロールのプロパティ]ウィンドウでそれを見るべき
myControl.SomeEvent += new MyEventHandler(handlerName);
:
//Define your Custom Event argument
public class MyEventArgs : EventArgs
{
//Define some fields of your custom event argument
private int m_SomeValue = 0;
//Define some properties of your custom event argument
public int SomeValue
{
get { return m_SomeValue; }
set { m_SomeValue = value; }
}
}
//Define the event handler data type
public delegate void MyEventHandler(object sender, MyEventArgs e);
//Define the object which holds the outside event handlers
public event MyEventHandler SomeEvent;
//Define the function which will generate the event
public virtual void OnSomeEvent(MyEventArgs e)
{
if (SomeEvent != null)
SomeEvent(this, e);
}
.
. //Then later in the control
.
{
//We need new data
//Create the event arguments
MyEventArgs newEvent = new MyEventArgs();
//Set the values
newEvent.SomeValue = 17;
//Call the event generating function
OnSomeEvent(newEvent);
}
フォームではただのようなものを使用します。
メタデータ属性を使用してイベントを盛り上げることはできますが、これらを発見するには任せます。
いい質問です。私はそれが含まれているコントロールからのデータが必要な場合、私はユーザーコントロールの必要性を参照してくださいない。この場合、ユーザーコントロールは使用しないでください。あなたは、この種のロジックをユーザコントロールの中でコーディングすべきではありません。 – Pabuc
@パブック - 私のユーザーコントロールが何をしているのか分からないので、あなたのステートメントは無意味です。 – Hosea146
私はPabucと一緒です。私はあなたのUser Controlを見ることができませんが、Separation of Concernsに違反しているように思えます。私はこの問題を解決する小さな再設計があるのだろうかと思います。 –