我有一个usercontrol,它在与Web服务通信后引发一个事件.父项在引发时处理此事件.我认为正确的方法是将webservice返回的对象作为eventargs传递给父对象???
如果这是正确的方法,我似乎无法找到如何这样做的说明.
用户控件
public event EventHandler LoginCompleted;
Run Code Online (Sandbox Code Playgroud)
然后在服务返回biz对象之后:
if (this.LoginCompleted != null)
{
this.LoginCompleted(this, new EventArgs() //this is where I would attach / pass my biz object no?);
}
Run Code Online (Sandbox Code Playgroud)
亲
ctrl_Login.LoginCompleted += ctrl_Login_LoginCompleted;
....snip....
void ctrl_Login_LoginCompleted(object sender, EventArgs e)
{
//get my object returned by login
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是将用户对象恢复为父级的"已批准"方法是什么?创建一个属性类,一切都可以访问并将其放在那里?
Dan*_*rth 42
你将不得不使用声明你的活动EventHandler<T>,其中T是您的类派生自EventArgs:
public event EventHandler<LoginCompletedEventArgs> LoginCompleted;
Run Code Online (Sandbox Code Playgroud)
LoginCompletedEventArgs 可能看起来像这样:
public class LoginCompletedEventArgs : EventArgs
{
private readonly YourBusinessObject _businessObject;
public LoginCompletedEventArgs(YourBusinessObject businessObject)
{
_businessObject = businessObject;
}
public YourBusinessObject BusinessObject
{
get { return _businessObject; }
}
}
Run Code Online (Sandbox Code Playgroud)
用法如下:
private void RaiseLoginCompleted(YourBusinessObject businessObject)
{
var handler = LoginCompleted;
if(handler == null)
return;
handler(this, new LoginCompletedEventArgs(businessObject));
}
Run Code Online (Sandbox Code Playgroud)
请注意我的实施方式RaiseLoginCompleted.这是引发事件的线程安全版本.我消除了NullReferenceException在竞争条件场景中可能发生的情况,其中一个线程想要引发事件而另一个线程在if检查之后但在实际调用处理程序之前取消订阅最后一个处理程序.
Joe*_*e.P 10
好吧,你可以做到这一切,或者你可以将一个委托定义为你的EventHandler并在其签名中定义你的属性.
如:
public delegate void MyEventEventHandler(int prop1, string prop2, object prop3...);
public event MyEventEventHandler MyEvent;
Run Code Online (Sandbox Code Playgroud)
我建议使用命名元组EventHandler<TEventArgs>。
我喜欢老狗的回答。Microsoft 已经拥有此委托EventHandler< TEventArgs >。
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
Run Code Online (Sandbox Code Playgroud)
您不需要继承自EventArgs.
使用命名元组声明您的事件处理程序。
public event EventHandler<(int id, string message, object LoginObject)> LoginCompleted;
Run Code Online (Sandbox Code Playgroud)
在您的客户端代码中,将方法分配给 LoginCompleted 事件处理程序
选项 1:使用 lambda
LoginCompleted += (o, e) =>
{
Console.WriteLine($"Hello, sender is {o.ToString()}! id is {e.id}, message is {e.message}, and LoginObject is {e.LoginObject.ToString()}. ");
};
Run Code Online (Sandbox Code Playgroud)
选项2:调用本地方法
LoginCompleted += onLoginCompleted;
private static void onLoginCompleted (object sender, (int id, string message, object LoginObject) e)
{
Console.WriteLine($"Hello, sender is {sender.ToString()}! id is {e.id}, message is {e.message}, and LoginObject is {e.LoginObject.ToString()}. ");
}
Run Code Online (Sandbox Code Playgroud)
我只是写了一个例子,请参考我的repo
小智 5
我个人喜欢 Toni Petrina 的方法(参见https://coderwall.com/p/wkzizq/generic-eventargs-class)。它与接受的答案不同,因为您不必创建特殊的 EventHandler 类(例如LoginCompletedEventArgs)。
(注意:我使用的是 VS 2015 和 C# v6。在旧版本的 Visual Studio 和 C# 中,您可能需要添加using System.Linq;)
创建一个继承自 EventArgs 的通用 EventArgs<T> 类...
class EventArgs<T> : EventArgs {
public T Value { get; private set; }
public EventArgs(T val) {
Value = val;
}
}
Run Code Online (Sandbox Code Playgroud)
声明您的事件处理程序...
public event EventHandler<EventArgs<object>> LoginCompleted;
Run Code Online (Sandbox Code Playgroud)
假设您已声明并分配了一个名为 的对象loginObject,请添加代码以引发事件...
private void RaiseLoginCompleted() {
if (LoginCompleted != null)
LoginCompleted(this, new EventArgs<object>(loginObject));
}
Run Code Online (Sandbox Code Playgroud)
在您的客户端代码中,添加LoginCompleted事件处理程序(使用 Linq 并调用本地方法)...
LoginCompleted += (o, e) => onLoginCompleted(e.Value); // calls a local method
void onLoginCompleted(LoginObject obj) {
// add your code here
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
49515 次 |
| 最近记录: |