从另一个用户控件访问用户控件的方法

时间:2012-11-16 08:44:01

标签: c# winforms user-controls

在我的表单上,我有2个继承FadeControl的UserControls(ButtonDiscount,ButtonAdvertisment)。 FadeControl继承UserControl类,用于在控件上执行自定义内容,如淡出。

我的2个UserControls每个只有一个按钮,因此这两个缺乏想象力的名称。

单击其中一个usercontrols上的那个按钮,我需要从另一个UserControl访问FadeControl中的方法。另一个按钮恰恰相反。

我已完成以下操作,点击UserControl ButtonDiscount中的事件:

private void button1_Click(object sender, EventArgs e)
{
    ButtonAdvertisment ba = (ButtonAdvertisment)this.Parent.Controls.Find("buttonAdvertisment1", true)[0];
    ba.FadeOut(true);
}

它就像一个魅力,但我不认为这是正确的方法,是否有另一种方法从其他UserControl的父类访问该方法?

我不能通过UserControl构造函数传递它,设计师每次都会崩溃。

2 个答案:

答案 0 :(得分:0)

你有2个独立的用户控件,彼此之间并不了解,这很好并且可以保持代码松散耦合。现在你要做的就是让他们以某种方式了解彼此并进行沟通。让他们彼此意识到打破了松散耦合,这是一个糟糕的设计。

我建议创建一个第三个控件,它将两个控制在一起,并将处理它们之间的所有通信。每个原始控件都有公共事件,父控件可以订阅并适当处理。

检查调解员模式以获取更多信息:http://en.wikipedia.org/wiki/Mediator_pattern

答案 1 :(得分:0)

你做得很好 - 你可以通过公开当你点击那些控件中的按钮时触发的事件,然后将引用传递给彼此(订阅那些,编写代码以淡化'this'控件)来做到这一点)。

然而,对于一个简单的解决方案来说,这可能有点太多了。

我对你的解决方案的看法是,如果你要更改控件的名称,那么它就会停止工作。你可以这样做:

var ba = this.Parent.Controls.OfType<ButtonAdvertisement>().FirstOrDefault();

这样你就不再依赖于控件名 - 而是控件的类型。您需要在代码文件中使用using System.Linq;才能生效。当然,这取决于父级中只有该控件类型的另一个实例。

如果您对我提到的第一个解决方案感兴趣,那么此代码段应该有助于演示:

public class FadeControl {
  public event EventHandler Clicked;

  public void FadeOut(bool b){

  }

  public void AttachTo(FadeControl other){
    //splitting this operation to a public and private allows us to 
    //initiate an attach publicly, but then recurse privately without 
    //causing a stack overflow
    AttachToInternal(other);
    other.AttachToInternal(this);
  }

  private void AttachToInternal(FadeControl other){
    other.Clicked += Attached_Clicked;
  }

  protected virtual void Attached_Clicked(object sender, EventArgs e)
  {
    //fade me out
    FadeOut(true);
  }

  // provides a way for the deriving class to raise the Clicked event
  protected void OnButtonClicked(){
    if(Clicked != null) Clicked(this, null);
  }
}

public class ButtonDiscount : FadeControl {
  Button _button;

  //omitted: designer code

  //this is your handler for the _button clicked event 

  private void _button_Clicked(object sender, EventArgs e){
    //call the base class' OnButtonClicked method - to raise the event
    OnButtonClicked();
    //TODO: do work.
  }
}

//omitted - code for the ButtonAdvertisement class

完成后 - 在您的表单中,假设您的表单中有_buttonAdvertisement_buttonDiscount成员,之后他们已初始化 - 您只需:< / p>

_buttonAdvertisement.AttachTo(_buttonDiscount);

这将立即将两个控件彼此绑定。

注意 - 在回复下面的评论时 - 我已经在FadeControl中为另一个FadeControl的Clicked事件保护和虚拟做了事件处理程序 - 所以你可以覆盖它。