C#用户控制 - 如何告诉控件需要数据的包含对象

时间:2010-12-16 15:01:21

标签: c# user-controls

我正在创建一个C#WinForms用户控件。有时用户控件将需要包含它的表单中的数据。如何让用户控件告诉包含它的表单它需要一些数据?

谢谢!

5 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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
}

答案 2 :(得分: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);

由于您的活动是公开的,您也应该在控件的“属性”窗口中看到它。

您可以使用元数据属性来理解事件,但我会让您发现这些属性。

答案 3 :(得分:0)

对我来说似乎有点模糊,但是:

使其成为包含WinForm的事件,以便每次准备好一些数据时,可以在一对多模型中通知所有订阅者;或者在订阅控件中以一对一的模式将其作为事件,在该模型中,它调用容器的方法来检索此类数据?

答案 4 :(得分:0)

这取决于何时需要将数据推送到UserControl。表单上是否有事件需要在UserControl中移动数据?如果是这样的话......只需抓住你的实例,然后通过公共财产将数据推送到UserControl。

如果是这种情况没有使用事件或者表格以某种方式“接收数据”,那么在表格上公开event,如......

public event DataHandler ReceivedData;

...并允许UserControl或任何其他容器注册事件并通过自定义事件args接收数据。将事件推入UserControl并强制表单锁定到UserControl似乎是向后的,因为表单是数据的发起者。