2010-12-16 55 views
4

我正在創建一個C#WinForms用戶控件。有時候用戶控件需要包含它的表單中的數據。我該如何讓用戶控件告訴包含它的表單需要一些數據?C#用戶控件 - 如何判斷控件需要數據的包含對象

謝謝!

+1

好問題;但如果它需要來自其包含的控件的數據,我不認爲需要用戶控件。在這種情況下不應該使用Usercontrols。你不應該在usercontrol中編寫這種邏輯。 – Pabuc 2010-12-16 15:10:10

+2

@Pabuc - 由於您不知道我的用戶控件在做什麼,因此您的陳述毫無意義。 – Hosea146 2010-12-16 15:32:06

+0

我與Pabuc。我看不到您的用戶控件,但這聽起來像您可能違反了問題分離。我想知道是否有一個小的重新設計可以解決這個問題。 – 2011-06-20 20:42:02

回答

4

您可以將窗體訂閱到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; 
} 
0

似乎有點含糊,我,但:

使其在含有WinForm的事件,這樣每次一些數據已準備好所有的用戶可以在一個一對多的模型通知;或者使其成爲訂閱控件中的一個事件,以一對一的模式,在這種模式下,它會調用容器的方法來檢索這些數據?

+0

OP - 這是觀察者模式。谷歌它,這可能是你在找什麼。 – 2010-12-16 15:16:38

1

在事件參數可編輯的用戶控件上創建一個事件。讓表單附加一個處理程序到那個更新這些字段的事件。在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 
} 
+0

然後,當另一個控件出現需要的數據時,您需要返回到您的對象並註冊另一個處理程序...唉...讓關心數據註冊的人成爲它。 – 2010-12-16 15:43:52

0

這取決於何時需要將數據推送到UserControl。是否有事件發生在窗體上,將驅動需要在UserControl內移動數據?如果是這樣的話......只需抓住你的實例,並通過公共屬性將數據推送到UserControl。

如果這是在不被使用的事件的情況下,或以某種方式或另一種形式「接收數據」,則暴露所述表格上的event如...

public event DataHandler ReceivedData; 

...並允許UserControl或任何其他容器註冊該事件並通過自定義事件參數接收數據。由於Form是數據的發起者,所以將事件推入UserControl並強制Form鎖定到UserControl似乎倒退了。

+0

不同意。將事件放在窗體上並讓用戶控件附加到窗體上是很危險的,因爲清理順序會令人困惑。你可以很容易地結束循環引用,既不允許被丟棄。很難調試那種內存泄漏。 – pdr 2010-12-16 15:22:35

+0

@pdr因爲它令人困惑,它使它錯了嗎?嗯......這種情況下的表單(可以是任何對象)是數據背後的對象。如果其他對象需要來自此表單的數據,則他們也應該能夠訂閱事件並接收數據。當他提出數據的時候強制表單鎖定每一個對象都沒有好處。 – 2010-12-16 15:29:41

+0

我不是說這種方法是「錯誤的」,我說這是危險的。但是,答案中的最後一句話顯然是錯誤的。 – pdr 2010-12-16 15:35:24

1

創建在用戶控件的自定義事件,並有形式鉤進去。如果您需要自定義事件參數,則也可以創建這些參數。

在用戶控件:

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

在你的形式只是使用類似:

myControl.SomeEvent += new MyEventHandler(handlerName); 

由於您的活動是公開的,你應該看到它在你的控件的屬性窗口爲好。

您可以使用元數據屬性來欣賞事件,但是我可以讓您發現這些。

相關問題