الكائن المرسل يلقي في معالج الحدث باستخدام GetType (). اسم

StackOverflow https://stackoverflow.com/questions/634112

  •  10-07-2019
  •  | 
  •  

سؤال

ولدي معالج حدث للمربع نص وكذلك لRichTextBox. رمز غير متطابقة، ولكن

في معالج رقم 1 أفعل:

RichTextBox tb = (RichTextBox)sender

في معالج رقم 2 وفقا لذلك:

TextBox tb = (TextBox)sender

وبذلك أستطيع التعامل بشكل كامل لسيطرة الإرسال. ما أريد أن أعرفه هو كيف يمكن ط يلقي الكائن المرسلة إلى مربع نص أو RichTextbox وفقا لنوعها باستخدام

sender.GetType().Name

وثم إنشاء عنصر تحكم في وقت التشغيل والعمل معها. أن طريق أنا فقط بحاجة الى وظيفة معالج حدث واحد: أقل رمز، وأخطاء أقل وأسهل للحفاظ على والجافة: -)

هل كانت مفيدة؟

المحلول

واعتمادا على ما الخصائص التي تحتاج إليها، هل يمكن أن يلقي المرسل باعتباره TextBoxBase على حد سواء مربع نص وRichTextBox على حد سواء وراثة من أن الطبقة الفرعية.

نصائح أخرى

ولست مضطرا ابدا للادلاء. كنت أعتقد بنفس الطريقة عندما بدأت، وهذا "النمط" غير صحيح، وليس من المنطقي حقا.

وأفضل رهان هو استخدام شيء من هذا القبيل:

if (sender is TextBox)
{
  TextBox tb = (TextBox)sender;
}
else if (sender is RichTextBox)
{
  RichTextBox rtb = (RichTextBox)sender;
}
else
{
  // etc
}

وأنا أعلم أن هذه هي وظيفة قديمة جدا ولكن في الإطار 4 هل يمكن أن يلقي المرسل باعتباره التحكم:

Control cntrl = (Control)sender;
cntrl.Text = "This is a " + sender.GetType().ToString();

ملحوظة كنت قادرا على الرجوع الضوابط أن جميع الضوابط المختلفة ان تكون مشتركة (أي النص) فقط.

RichTextBox textbox = sender as RichTextBox;
if (textbox != null)
{
   // do stuff as a rtb
   textbox.Text = "I'm a rtb";
   return;
}

TextBox textbox = sender as TextBox;
if (textbox != null)
{
   // do stuff as a textbox
   textbox.Text = "I'm a textbox";
}

ويمكن أن يتم إلا صب في الترجمة من الوقت وبالتالي كنت بحاجة لمعرفة الأنواع التي ترغب في الإدلاء عليها في الترجمة من الوقت. A نوع وقت التشغيل (على النحو الذي عاد GetType ()) بالتالي لا يمكن استخدامها عند الصب.

وإذا كان تعدد الأشكال التي تريدها هل يمكن الوصول إلى خاصية الاسم من خلال التأمل. أنا لن أذهب بهذه الطريقة على الرغم من مجرد أن تكون قادرة على إعادة استخدام معالجات الأحداث.

إذا كنت تريد الكتابة قوية، فئة أساسية مشتركة أو واجهة على المرسلين اثنين هي السبيل الوحيد للمضي قدما.

وبدلا من اسم نوع هل يمكن استخدام " و ".

إذا كنت ترغب فقط في معرفة نوع ولا تحتاج إلى مرجع كائن:

if (sender is RichTextBox)
{
    // ...
}
else if (sender is TextBox)
{
    // ...
}

ولكن هل عموما لا نريد من وجوه: C # 7 لديه جملة لطيفة التي تسمح لك لاختبار والحصول على مضمنة القيمة:

if (sender is RichTextBox richTextBox)
{
    richTextBox.Text = "I am rich";
}
else if (sender is TextBox textBox)
{
    textBox.Text = "I am not rich";
}

ويمكنك أيضا استخدام متغير مضمنة مؤقت للتعامل مع المدلى بها بالنسبة لك.

if (sender is RichTextBox tb)
{
    // ... //
} 
else if (sender is TextBox tb)
{
    // ... //
}

وإذا كان رمز غير متطابقة، لا تحتاج إلى الرعاية؟ أنا أتساءل عما إذا كان الصب إلى Control لن تعطيك كل ما تحتاجه ...

واحد معالج معقدة ليست بالضرورة أفضل من عدة معالجات بسيطة. وفي كلتا الحالتين، إذا كنت <م> هل لديك إلى السير في هذا الطريق "، كما" / "هو" الأفضل (أنها لا تعتمد على الاوتار الخ):

TextBox tb = sender as TextBox;
if(tb!=null) {/* TextBox specific code */}
...

وإذا كنت لا ترغب في تكرار رمز فإنك يمكن أن يلقي كل من الضوابط، ريفاكتور الإجراءات المشتركة لطريقة منفصل التي تأخذ TextBoxBase كحجة. وفي معالجات الأحداث الخاصة بك تحويل الضوابط لSystem.Windows.Forms.TextBoxBase كما تستمد كل من عناصر التحكم من TexbBoxBase واستدعاء الأسلوب.

تجدر الإشارة إذا كنت بحاجة إلى خصائص معينة في أي من هذه الضوابط فإن هذا إعادة بيع ديون متعود العمل.

ونسخة عام من رمز أعلاه:

public static void CastAndUse<T>(object item, Action<T> action) where T : class
{
    T thing = item as T;

    if (thing != null)
    {
        action(thing);
    }
}

والمستخدمة على النحو التالي:

CastAndUse(sender, new Action((foo) => foo = bar));

وليس الكمال، ولكن في متناول يدي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top