将控件视为组合框或文本框

本文关键字:文本 组合 控件 | 更新日期: 2023-09-27 18:11:23

解决以下问题的最佳方法是什么?

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属性已经足够复杂了。你可以假设我保证有一个组合框或一个文本框。

我的第一个想法是为T使用具有多个类型的泛型,但似乎这在。net中是不可能的:

public string GetAutoCompleteModeProperty<T>(T control) where T: ComboBox, TextBox // this does not work, of course

遗憾的是这两个控件没有一个共同的基类。

注意:这是一个更一般的问题,用于最小化的例子。在我的情况下,我还想访问/操纵其他AutoComplete*属性(这也是两个控件的共同之处)。

谢谢你的建议!

将控件视为组合框或文本框

dynamic currentControl =  control;
string text = currentControl.WhatEver;

但是,它抛出一个异常(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException),如果currentControl不具有WhatEver属性

使用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);

你可以把它移到一个helper方法中,以节省重写代码的时间。

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
}

这取决于你想要达到的目标。如果您只对text属性感兴趣,那么这实际上是从Control类继承的—因此您不需要强制转换对象。所以你只需要:

foreach (var control in this.Controls)
{
    value = control.Text;
    ...
}

然而,如果您需要更复杂的逻辑,您应该考虑重新考虑您的控制流。我建议使用View/Presenter模型,单独处理每个事件——单一职责的方法可以大大降低复杂性。

如果你给你的视图分配了一个带有预期属性的接口——例如view。FirstName、视图。主机名或视图。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
}

我希望这是一些帮助!