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

C#用户控件-如何告知控件需要数据的包含对象,c#,user-controls,C#,User Controls,我正在创建一个C#WinForms用户控件。有时,用户控件需要来自其所包含表单的数据。如何让用户控件告诉包含它的表单它需要一些数据 谢谢 对我来说似乎有点模糊,但是: 将其设置为包含WinForm的事件,以便每次某些数据就绪时,都可以以一对多模型通知所有订阅者;或者以一对一模型将其作为订阅控件中的事件,在该模型中,它调用检索此类数据的容器方法?在用户控件上创建一个事件,其中事件参数是可编辑的。让表单将处理程序附加到该事件,该事件将更新这些字段。在OneEvent方法中使用这些字段 [未经测试]

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


谢谢

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


将其设置为包含WinForm的事件,以便每次某些数据就绪时,都可以以一对多模型通知所有订阅者;或者以一对一模型将其作为订阅控件中的事件,在该模型中,它调用检索此类数据的容器方法?

在用户控件上创建一个事件,其中事件参数是可编辑的。让表单将处理程序附加到该事件,该事件将更新这些字段。在OneEvent方法中使用这些字段

[未经测试] 例如


这取决于何时需要将数据推送到UserControl。表单上是否发生了事件,导致需要在UserControl中移动数据?如果是这样的话……只需在此时抓取您的实例,并通过公共属性将数据向下推送到UserControl

如果在这种情况下,事件未被使用,或者表单以某种方式“接收数据”,则在表单上公开事件,例如

public event DataHandler ReceivedData;

…并允许UserControl或任何其他容器注册事件并通过自定义事件参数接收数据。将事件推入UserControl并强制窗体锁定UserControl似乎是向后的,因为窗体是数据的启动器。

您可以将窗体订阅到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;
}
//您的示例控件
公共类MyUserControl:Control
{
公共事件处理程序嵌入数据;
公共数据数据{get;set;}
私有类DoSomething()
{
如果(INEEDATA!=null)INEEDATA(本,null);
}
}
...
//如果尚未添加控件,则返回窗体。
var_myUserControl=new myUserControl();
私有void Form1\u加载(对象发送方、事件参数e)
{
_myUserControl.INeedData+=新事件处理程序(myUserControl\u INeedData);
this.Controls.Add(myUserControl);
}
void MyUserControl_INeedData(对象发送方,事件参数e)
{
_myUserControl.Data=SomeData;
}

在用户控件中创建一个自定义事件,并将表单挂钩插入其中。如果需要自定义事件参数,也可以创建这些参数

在用户控制中:

//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);
因为您的事件是公共的,所以您也应该在控件的属性窗口中看到它


您可以使用元数据属性想象事件,但我将这些留给您去发现。

好问题;但是,如果usercontrol需要来自其包含控件的数据,我认为它不需要usercontrol。在这种情况下不应使用Usercontrols。您不应该在usercontrol内部编写这种逻辑。@Pabuc-因为您不知道我的用户控件在做什么,所以您的语句毫无意义。我支持Pabuc。我看不到您的用户控件,但听起来您可能违反了关注点分离。我想知道是否有一个小的重新设计可以解决这个问题。应该用什么来代替?例如,我有一个分页器,它呈现链接。我有一个对象,它生成需要由ascx模板渲染的超链接对象。用户控件似乎是一种将分页放在页面上而不进行大量绑定的枯燥方式。在MVC框架中,我只会使用某种模板继承,但显然我不能在asp.net webforms?OP中这样做-这是观察者模式。谷歌它,这可能是你正在寻找的。不同意。将事件放在表单上并将用户控件附加到表单上是危险的,因为清理的顺序会混淆。您很容易得到循环引用,这两种引用都不允许被处理。调试这种内存泄漏非常困难。@pdr因为它让人困惑而出错?嗯……这种情况下的表单(可以是任何对象)就是数据背后的对象。如果其他对象需要此表单中的数据,它们还应该能够订阅事件并接收数据。当他是提出数据的人时,强迫表单锁定每个对象是没有好处的。我不是说这种方法是“错误的”,我是说它是危险的。然而,你的答案中的最后一句是完全错误的。@pdr它怎么完全错误?为什么要让数据的发起人订阅整个应用程序中不同对象上的事件?你的对象上没有事件,并强制按钮订阅你的对象,让你知道他已被单击…这有什么不同吗?对不起,我不遵循你的示例。但是我不能马上想到任何一种情况,在这种情况下,我希望子对象订阅父对象上的事件(其中子/父对象被定义为封装子对象的父对象)。这就是为什么我们有观察者模式,然后当另一个控件出现时,需要返回到对象并注册另一个处理程序所需的数据…呸…让关心数据的人为它注册。
myControl.SomeEvent += new MyEventHandler(handlerName);