Рассматривать элемент управления как ComboBox или TextBox
каков наилучший способ решить следующее ?
foreach (Control control in this.Controls)
{
if (control is ComboBox || control is TextBox)
{
ComboBox controlCombobox = control as ComboBox;
TextBox controlTextbox = control as TextBox;
AutoCompleteMode value = AutoCompleteMode.None;
if (controlCombobox != null)
{
value = controlCombobox.AutoCompleteMode;
}
else if (controlTextbox != null)
{
value = controlTextbox.AutoCompleteMode;
}
// ...
}
}
вы видите, что это достаточно сложно, чтобы получить свойство AutoCompleteMode. Вы можете предположить, что гарантируется, что у меня есть ComboBox или TextBox.
моей первой идеей было использовать generic с несколькими типами для T, но кажется, что это невозможно в .NET:
public string GetAutoCompleteModeProperty<T>(T control) where T: ComboBox, TextBox // this does not work, of course
к сожалению, оба элемента управления не имеют общей базы класс.
Примечание: это должен быть более общий вопрос, используемый с минимизированным примером. В моем случае я также хочу получить доступ / манипулировать другими автозаполнением* - proprties (которые также имеют общие элементы управления).
Спасибо за идеи!
3 ответов
использовать Type.GetType()
. Вам просто нужно ввести string
представление вашей собственности.
if (sender is ComboBox || sender is TextBox)
{
var type = Type.GetType(sender.GetType().AssemblyQualifiedName, false, true);
var textValue = type.GetProperty("Text").GetValue(sender, null);
}
это также позволяет установить значение ваших свойств тоже.
type.GetProperty("Text").SetValue(sender, "This is a test", null);
вы можете переместить это в вспомогательный метод для сохранения кода перезаписи.
public void SetProperty(Type t, object sender, string property, object value)
{
t.GetProperty(property).SetValue(sender, value, null);
}
public object GetPropertyValue(Type t, object sender, string property)
{
t.GetProperty(property).GetValue(sender, null);
}
существует также место для обработки исключений с помощью этого метода.
var property = t.GetProperty("AutoCompleteMode");
if (property == null)
{
//Do whatever you need to do
}
dynamic currentControl = control;
string text = currentControl.WhatEver;
но он создает исключение (Microsoft.Используется CSharp.Рантимебиндер.RuntimeBinderException), если currentControl не имеет какого-либо свойства
зависит от того, чего вы пытаетесь достичь. Если вас интересует только свойство text, то это фактически наследуется от управления class-поэтому вам не нужно бросать объект. Так что вам просто нужно :
foreach (var control in this.Controls)
{
value = control.Text;
...
}
Если, однако, вам требуется более сложная логика, вы должны рассмотреть возможность переосмысления потока управления. Я бы предложил модель представления / презентатора и обрабатывал каждое событие индивидуально-подход одиночной ответственности может значительно уменьшите сложность.
Если вы назначаете вашему виду интерфейс с ожидаемыми свойствами-например, вид.Имя, вид.HouseName или посмотреть.CountrySelection - таким образом, реализация (т. е. TextBox, ComboBox и т. д.) скрыта. Итак:
public interface IMyView
{
string FirstName { get; }
string HouseName { get;}
string CountrySelection { get; }
}
public class MyView : Form, IMyView
{
public string FirstName { get { return this.FirstName.Text; } } // Textbox
public string HouseName { get { return this.HouseName.Text; } } // Textbox
public string CountrySelection { get { return this.CountryList.Text; } // Combobox
}
Я надеюсь, что это какой-то помощи!