0

在我的表单上,我有 2 个继承 FadeControl 的用户控件(ButtonDiscount、ButtonAdvertisment)。FadeControl 继承 UserControl 类并用于对控件执行自定义操作,例如淡出。

我的 2 个用户控件每个都只有一个按钮,因此这两个名字没有想象力。

单击其中一个用户控件上的该按钮时,我需要从另一个用户控件访问 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 构造函数传递它,设计者每次都会崩溃。

4

2 回答 2

0

您有 2 个独立的用户控件,它们彼此不知道,这很好,并且可以使您的代码保持松散耦合。现在你要做的是让他们以某种方式了解彼此并进行交流。让它们相互了解会破坏松散耦合,这是一个糟糕的设计。

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

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

于 2012-11-16T08:54:43.817 回答
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

_buttonAdvertisement.AttachTo(_buttonDiscount);

这将立即将两个控件相互绑定。

注意 - 回应下面的评论 - 我已经FadeControl为另一个 FadeControl 的Clicked事件创建了事件处理程序,并且是受保护的和虚拟的 - 所以你可以覆盖它。

于 2012-11-16T08:55:11.833 回答