0

I have a method that has a Control parameter. I want to get the value of the control. So if it is a TextBox get the value of the Text property; if it is a NumericUpDown get the value of the Value property and so on.

The problem is that I cannot write something like this:

Method(Control control)
{
    control.Text;
}

or

Method(Control control)
{
    control.Value;
}

Because there is no guarantee that the control has one of these properties, and what is its name if it does have it. Is there a way to do something like that?

Michael Haddad
  • 4,085
  • 7
  • 42
  • 82
  • There is `if (foo is TextBox)...` construct in C#... Very hard to see how far you want to go with that without seeing your current code and direction you want to improve it. – Alexei Levenkov Nov 11 '17 at 20:21
  • @AlexeiLevenkov - well, I am not sure what exactly could be a solution. I did try the `if` statement you suggested but it's not elegant. I thought maybe there is some property inside `Control` that refers to the property that holds the value or something like that. I couldn't find any, but I thought maybe there is some other way. – Michael Haddad Nov 11 '17 at 20:24
  • There isn't such property in control class. – Reza Aghaei Nov 11 '17 at 20:32

1 Answers1

3

There isn't such common Value property in Control class.

You should use some if/else or switch/case or a dictionary approach to get the value from the control. Because you know what property you need. The control just provides properties.

For example for a ComboBox, what is the value? Is it SelectedItem, SelectedIndex, SelectedValue, Text? It's usage/opinion based.

The nearest thing to what you are looking for, is relying on DefaultProperty attribute of controls to get the value from that property using relfection. For example, having this method:

public object GetDefaultPropertyValue(Control c)
{
    var defaultPropertyAttribute = c.GetType().GetCustomAttributes(true)
        .OfType<DefaultPropertyAttribute>().FirstOrDefault();
    var defaultProperty = defaultPropertyAttribute.Name;
    return c.GetType().GetProperty(defaultProperty).GetValue(c);
}

You can get values this way:

var controls = new List<Control> {
    new Button() { Text = "button1" },
    new NumericUpDown() { Value = 5 },
    new TextBox() { Text = "some text" },
    new CheckBox() { Checked = true }
};

var values = controls.Select(x => GetDefaultPropertyValue(x)).ToList();
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Nice. Also value of getting such value if of questionable value :) - as result of the method will have wildly different types and it is hard for me to see what OP is going to do with such mix of numbers, string, bools and more complicated objects. But this definitely gets them the closest thing to what they asked. – Alexei Levenkov Nov 11 '17 at 20:44
  • 1
    @AlexeiLevenkov I also have no idea about the reason behind this question and to me it seems to be an [XY Problem](https://meta.stackexchange.com/q/66377/308647). But the OP should know they should use some if/else or switch/case or a dictionary approach to get the value from the control. Because they know what property they need. The control just provides properties. For example for a ComboBox, what is the value? Is it SelectedItem, SelectedIndex, SelectedValue, Text? It's usage/opinion based. – Reza Aghaei Nov 11 '17 at 20:59
  • Basically, I have a method that should get a control as a parameter, and validate the value of the control. – Michael Haddad Nov 12 '17 at 17:02
  • @Sipo So you need to know about the type of value and it means you need some type casting and if/else or switch/case. For validation, you may want to consider [some other options](https://stackoverflow.com/a/35993185/3110834). – Reza Aghaei Nov 13 '17 at 01:05
  • Thanks. I actually do use the `Validating` event and an `ErrorProvider`. – Michael Haddad Nov 13 '17 at 06:31