我正在创建一个C# WinForms用户控件。有时用户控件需要从包含它的表单中获取数据。我该如何让用户控件告诉包含它的表单它需要一些数据呢?
谢谢!
我正在创建一个C# WinForms用户控件。有时用户控件需要从包含它的表单中获取数据。我该如何让用户控件告诉包含它的表单它需要一些数据呢?
谢谢!
您可以订阅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;
}
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
}
在用户控件中:
//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内部移动数据的需求?如果是这样...只需在该点获取您的实例,并通过公共属性将数据向下推送到UserControl。
如果这种情况不使用事件或表单以某种方式“接收数据”,则可以在表单上公开event,例如...
public event DataHandler ReceivedData;
...并允许UserControl或任何其他容器注册事件并通过自定义事件参数接收数据。将事件推入UserControl并强制Form依附于UserControl似乎是反向的,因为Form是数据的发起者。
对我来说有点模糊,但是:
将其作为包含 WinForm 中的事件,以便每当准备好一些数据时,所有订阅者都可以在一对多模式下得到通知;或者将其作为订阅控件中的事件,在一对一模式下调用容器的方法来检索这些数据?