3

I'm using the following code to clear all the textboxes on my form

 private void ClearTextBoxes()
     {
         Action<Control.ControlCollection> func = null;

         func = (controls) =>
             {
                 foreach (Control control in controls)
                     if (control is TextBox)
                         (control as TextBox).Clear();
                     else
                         func(control.Controls);
             };
          func(Controls);

     }

However, it also clears a DomainUpDown, which in turn kicks out a warning because its text field is empty, how can I prevent this from happening?

olydis
  • 3,192
  • 13
  • 28
NigeC
  • 137
  • 3
  • 8

4 Answers4

2

Be careful, DomainUpDown is a container!

If you want to stick with most of your code, change

else
    func(control.Controls);

to

else if (!(control is DomainUpDown))
    func(control.Controls);

The reason of the behaviour you described is the following: DomainUpDown's Control property contains - along with other things - a TextBox, so you might explicitly want to exclude it from being handled the same way as other controls ;)

Otherwise you will recurse on it as if it was a Panel or similar, and therefore also clear its text!

olydis
  • 3,192
  • 13
  • 28
1

use

if (control.GetType() == typeof(TextBox))

instead of

if (control is TextBox)

that clears only the TextBoxes, and leaves the DUDs :)

the 'is' operator is not checking the type of the arguments, but checks if they are compatible (has to do with inheritance), and is commonly used to check interfaces.

MSDN:An is expression evaluates to true if the provided expression is non-null, and the provided object can be cast to the provided type without causing an exception to be thrown.

d.popov
  • 4,175
  • 1
  • 36
  • 47
  • Have you tried it out? I just tested. control.GetType() will return the actual type of the control. no way that this is TextBox. if not sure, use control.GetType().Name – d.popov Sep 20 '13 at 09:30
  • correct it is not - but when he recurses on `Controls` he will also recurse on `DomainUpDown` ;) there is nothing wrong with your code, it just does not solve his issue – olydis Sep 20 '13 at 09:32
  • yes, i see. Can somebody explain then why this it works when i try it in my sandbox? – d.popov Sep 20 '13 at 09:42
  • because you do not recurse on `Controls` in your sandbox? – olydis Sep 20 '13 at 09:47
  • No? using the code from the question. have you tried, or you just downvoted my answer. because it works on my machine. – d.popov Sep 20 '13 at 09:50
  • NO, read the question (and probably my answer), the problem he is having is a RESULT of recursing on `Controls` (which he HAS to do since he also wants to clear TextBoxes within containers!!!) - again: there is nothing wrong with your code, it just does not solve his issue – olydis Sep 20 '13 at 09:53
  • I downvoted it because it just does not solve his problem, just as literally every other answer :( – olydis Sep 20 '13 at 09:53
  • well, i think it solves it, because i tried it. I read your answer, and agree with it. I just asked anyone to say why my code also solves the problem, since it is like that on my PC :) I call the ClearTextBoxes function from the question AS IT IS - WITH the recursive call. I encourage you to try my code, before downvote and if you have explanation why it works, great. I stop commenting this issue anymore. – d.popov Sep 20 '13 at 10:04
  • okay trying it out now although I am 1000% sure it will not change anything – olydis Sep 20 '13 at 10:09
  • hihihihi you man are awesome! do you know why your code works? :D – olydis Sep 20 '13 at 10:19
  • yes, and i know you downvoted it, and we had all this long explanations... / no offense. I also don't have a good explanation about why – d.popov Sep 20 '13 at 10:21
  • ...just reflected on DUD, at least in .Net 4.0 it internally uses a class derived from textbox (which of course is ABSOLUTELY what you are preventing - which i never doubted :D) - but be careful, at least I am someone who very often derives from controls to adjust their behaviour! your solution works because of some INTERNALS of DUD, THAT ARE NOT GUARANTEED to be like that in the future (okay that is unlikely to happen)! instead my code uses information you DO know for sure AND will not change - just prevent recursing on controls instead of relying on internals... have a +1 – olydis Sep 20 '13 at 10:24
  • yes, that is why i saw the problem in the 'is' operator, and did not payed attention to the recursion problem. if you use a derived class the 'is' operator will return TRUE for all ancestors.That's why it seems bad idea for this functionality. i don't know why it does not go in the recursion, since DUD CONTAINS a TextBox inside, and both solutions work alone. – d.popov Sep 20 '13 at 10:43
  • well thats the thing, it GOES into the recursion with your solution, the textbox INSIDE dud just happens to actually be a derived one ;) i immediately downvoted your answer since it (because you explain `is` in so much detail) sort of suggested that DUD must be derived from `TextBox` and will therefore be spared with your code - which is not the case. instead the CHILD CONTROL of DUD happens to be derived from `TextBox` instead of just being one! So an explanation of that would have been nice, since it is a mere accident that your code works :D – olydis Sep 20 '13 at 11:10
0

This will help to clear textbox

 private void ClearInputs(ControlCollection ctrls)
        {
            foreach (Control ctrl in ctrls)
            {
                if (ctrl is TextBox)
                    ((TextBox)ctrl).Text = string.Empty;

                ClearInputs(ctrl.Controls);
            }
        }
Sasidharan
  • 3,676
  • 3
  • 19
  • 37
-1

If you only want to clear textboxes you could use

foreach(var control in Controls.OfType<TextBox>())
{
    control.Clear();
}

If your method is intended to be recursive, you may prefer this GetAll method

 foreach(var control in this.GetAll<TextBox>())
 foreach(var control in this.GetAll<TextBox>()
                            .Where(x => x.GetType().IsSubclassOf(typeof(TextBox))
Community
  • 1
  • 1
Sayse
  • 42,633
  • 14
  • 77
  • 146
  • indeed - I guess you are also clearing the `DomainUpDown` - this is semantically identical to what he already has ;) – olydis Sep 20 '13 at 09:16
  • @olydis - I checked and `DomainUpDown` doesn't have anything to do with a Textbox, so no, it won't be – Sayse Sep 20 '13 at 09:17
  • yes it does... `DomainUpDown`'s `Control` property **does** contain a `TextBox` - the text box the text of `DomainUpDown` is in ;) I checked it out as well ;) – olydis Sep 20 '13 at 09:20
  • very! don't take it personally or something, it just did not solve his problem before :) – olydis Sep 20 '13 at 09:23
  • and wait, it still does not... `GetAll` will still returns the inner `TextBox`... – olydis Sep 20 '13 at 09:24
  • you just cannot use `GetAll` here, since it will treat everything equally and **always** work on the `Controls` property – olydis Sep 20 '13 at 09:25