0

私のフォームには、FadeControl を継承する 2 つの UserControls (ButtonDiscount、ButtonAdvertisment) があります。FadeControl は UserControl クラスを継承し、フェードアウトなどのコントロールでカスタム処理を行うために使用されます。

私の 2 つの UserControls にはそれぞれボタンが 1 つしかないため、これら 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

あなたがやったことは大丈夫です-それらのコントロールのボタンをクリックしたときに発生するイベントを公開し、次に相互に参照を渡すことによってそれを行うことができます(それらをサブスクライブし、「this」コントロールをフェードするコードを記述します)。

ただし、これは単純なソリューションには少し手間がかかる可能性があります。

私があなたの解決策について言うことは、あなたがコントロールの名前を変更した場合、それは機能しなくなるということです。代わりに次のことができます。

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

そうすれば、コントロール名に縛られることはなくなりますが、コントロールのタイプに縛られることはありません。using System.Linq;これを機能させるには、コードファイルにが必要です。もちろん、これは、親にそのコントロールタイプの他のインスタンスが1つしかないという事実に依存しています。

私が言及した最初のソリューションに興味がある場合は、このコードスニペットが次のことを示すのに役立ちます。

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 に答える
0

お互いを認識しない 2 つの個別のユーザー コントロールがあります。これは優れており、コードを疎結合に保ちます。今、あなたがやろうとしていることは、彼らがお互いのことをどうにかして知り、コミュニケーションできるようにすることです。それらにお互いを認識させることは、疎結合を壊し、悪い設計です。

私が提案するのは、2 つをまとめてそれらの間のすべての通信を処理する 3 番目のコントロールを作成することです。元の各コントロールには、親コントロールがサブスクライブして適切に処理できるパブリック イベントがあります。

詳細については、メディエーター パターンを確認してください: http://en.wikipedia.org/wiki/Mediator_pattern

于 2012-11-16T08:54:43.817 に答える