C# 在运行时获取对象的成员
我有一个情况,不知道我的方法是否正确,请引导我通过这个。 假设我有一个包含许多控件的面板控件, 在运行时,我使用C# 在运行时获取对象的成员,c#,asp.net,.net,controls,C#,Asp.net,.net,Controls,我有一个情况,不知道我的方法是否正确,请引导我通过这个。 假设我有一个包含许多控件的面板控件, 在运行时,我使用 Panel1.控件属性, 现在在这些控件中,它们可以是任何文本框,按钮,下拉列表等等。 现在我想在运行时查找哪些控件属于哪种类型,然后查找该控件中是否包含任何特定属性&如果该属性存在,则设置该属性的值。 我想我必须在这里使用反射做一些事情,但不知道从哪里开始 示例代码: foreach (Control cntrl in Panel1.Controls) {
Panel1.控件
属性,
现在在这些控件中,它们可以是任何文本框
,按钮
,下拉列表
等等。
现在我想在运行时查找哪些控件属于哪种类型,然后查找该控件中是否包含任何特定属性&如果该属性存在,则设置该属性的值。
我想我必须在这里使用反射
做一些事情,但不知道从哪里开始
示例代码:
foreach (Control cntrl in Panel1.Controls)
{
//find type of the control
// find any specific property's existence in that control
// if property exists than set value of that property
}
对于在运行时执行此任务,也欢迎任何其他更相关的方法
对不起,我忘了提
我不想在这里使用is
关键字,因为控件是may类型的,我想创建一个全局函数,它可以用于任何面板,而不知道该面板中存在的控件类型
提前感谢。关键字就是您要找的
foreach(Control ctrl in Panel1.Controls)
{
if(ctrl is TextBox) //Is the control of type TextBox?
{
(TextBox)ctrl.Text = "TextBox Test!"; //Cast it to a TextBox
} else if(ctrl is Button) //Is the control of type Button?
{
(Button)ctrl.Text = "Button Test!";
}
}
从A型铸造到B型铸造有两种方法
(TextBox)ctrl
或
区别在于,第一种方法抛出异常,如果强制转换失败,第二种方法返回null。在您的情况下,您可以相当肯定它是正确的类型,因此使用哪种类型无关紧要。通过使用反射,您可以实现这一点
获取属性的元数据
,然后进行设置。这将允许您检查属性是否存在,并验证是否可以设置该属性:
foreach (Control cntrl in Panel1.Controls)
{
PropertyInfo prop = cntrl.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);
if(null != prop && prop.CanWrite)
{
prop.SetValue(cntrl, "MyName", null);
}
}
如果不想使用反射,请尝试此操作
foreach (Control cntrl in Panel1.Controls)
{
if(cntrl is TextBox)
{
TextBox txt = (TextBox)ctrl;
txt.Text = "Your value here";
// your textbox code here
}
else if(cntrl is DropDown)
{
// your DropDown code here
}
if(cntrl is Button)
{
// your Button code here
}
}
注意:is关键字检查对象是否与给定类型兼容。例如,以下代码可以确定对象是MyObject类型的实例,还是从MyObject派生的类型:您可以使用类型的扩展名
:
List<TextBox> textBoxes = myPanel.Controls.OfType<TextBox>().ToList();
string allText = string.Join("\n", textBoxes.ConvertAll(t => t.Text));
List textboxs=myPanel.Controls.OfType().ToList();
string allText=string.Join(“\n”,textboxs.ConvertAll(t=>t.Text));
上面的示例将在面板中找到所有TextBox控件,然后将它们的文本读入一个字符串。您可以尝试以下操作:
using System.Reflection; // reflection namespace
// get all public static properties of MyClass type
PropertyInfo[] propertyInfos;
foreach (Control cntrl in Panel1.Controls)
{
if( cntrl is TextBox)
{
propertyInfos = typeof(TextBox).GetProperties(BindingFlags.Public |
BindingFlags.Static);
//Loop thru property info n find the name using PropertyInfo.Name
if(property.Name == "property name")
//assign values
}
else
{
//others
}
}
您可以使用MSDN中的Type.GetProperties方法,如下所示:
public class TypeMain
{
public static void Main()
{
Type myType =(typeof(MyTypeClass));
// Get the public properties.
PropertyInfo[] myPropertyInfo = myType.GetProperties(BindingFlags.Public|BindingFlags.Instance);
Console.WriteLine("The mumber of public properties is {0}.", myPropertyInfo.Length);
// Display the public properties.
DisplayPropertyInfo(myPropertyInfo);
// Get the nonpublic properties.
PropertyInfo[] myPropertyInfo1 = myType.GetProperties(BindingFlags.NonPublic|BindingFlags.Instance);
Console.WriteLine("The number of protected properties is {0}.", myPropertyInfo1.Length);
// Display all the nonpublic properties.
DisplayPropertyInfo(myPropertyInfo1);
}
public static void DisplayPropertyInfo(PropertyInfo[] myPropertyInfo)
{
// Display information for all properties.
for(int i=0;i<myPropertyInfo.Length;i++)
{
PropertyInfo myPropInfo = (PropertyInfo)myPropertyInfo[i];
Console.WriteLine("The property name is {0}.", myPropInfo.Name);
Console.WriteLine("The property type is {0}.", myPropInfo.PropertyType);
}
}
公共类TypeMain
{
公共静态void Main()
{
类型myType=(typeof(MyTypeClass));
//获取公共属性。
PropertyInfo[]myPropertyInfo=myType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
WriteLine(“公共属性的数量为{0}.”,myPropertyInfo.Length);
//显示公共属性。
显示PropertyInfo(myPropertyInfo);
//获取非公共属性。
PropertyInfo[]MyPropertyInfo=myType.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
WriteLine(“受保护属性的数量为{0}.”,myPropertyInfo1.Length);
//显示所有非公共属性。
显示PropertyInfo(MyPropertyInfo 1);
}
公共静态void DisplayPropertyInfo(PropertyInfo[]myPropertyInfo)
{
//显示所有属性的信息。
对于(int i=0;i我自己找到了一个解决方案,请检查它,并告诉我从性能角度看它是否正确
foreach (Control cntrl in Panel1.Controls)
{
System.Reflection.PropertyInfo[] props = cntrl.GetType().GetProperties();
IEnumerable<System.Reflection.PropertyInfo> searchedProp = props.Where(delegate(System.Reflection.PropertyInfo p)
{
return p.Name.Contains("YourPropertyName");
});
if (searchedProp != null && searchedProp.Count() > 0)
searchedProp.First().SetValue(cntrl, true, null); // Here true should be replaced by the value that is allowed by the property you are setting at runtime
}
foreach(面板1.控件中的控件)
{
System.Reflection.PropertyInfo[]props=cntrl.GetType().GetProperties();
IEnumerable searchedProp=props.Where(委托(System.Reflection.PropertyInfo p)
{
返回p.Name.Contains(“YourPropertyName”);
});
if(searchedProp!=null&&searchedProp.Count()>0)
searchedProp.First().SetValue(cntrl,true,null);//此处true应替换为运行时设置的属性所允许的值
}
对于每个控件,获取控件类型和类型名称。
通过反射获取控件的值(如果需要)
对所需的属性执行“设置值”操作
foreach (Control control in panel1.Controls)
{
Type controlType = control.GetType();
switch (controlType.Name)
{
case "CheckBox":
if ((bool)controlType.GetProperty("Checked").GetValue(control,null))
controlType.GetProperty("Name").SetValue(control,"Check1",null);
break;
case "TextBox":
//TODO
break;
case "ComboBox":
//TODO
break;
default:
break;
}
}
}
你能提供更多关于你想知道哪些属性的具体细节,以及你是否事先知道你感兴趣的属性吗?你可能不需要思考。你能详细说明最后一部分吗?你到底是什么意思,为什么不想使用is
?这可能是一个稍微令人困惑的例子,因为 .Text
是控件的一个属性
。它相当直观,并且根据对象的类型显示如何分叉代码。没有太多按钮或文本框特定的属性如此直观。使用is
然后as
非常奇怪。可以使用as
然后检查null,或者is
然后一个cast.plz回顾我的问题我刚刚编辑了它,我不想使用is
keyword@JonSkeet你能解释一下为什么你更喜欢一个而不是另一个吗?从功能上来说,它是一样的,实际上我更喜欢在美学上使用as
,因为它创建了一个更统一的外观。使用as
看起来与使用类似de>是
,因此看起来更干净,即使演员阵容最终不会为空。(我确实编辑了我的答案,只是因为你可能是对的。)请回顾我的问题我刚刚编辑了它,我不想使用is
关键字是的,带反射的对我来说很合适,thanx。但我也发布了类似的东西,但我的一个更详细,你的看起来更苗条:)
foreach (Control control in panel1.Controls)
{
Type controlType = control.GetType();
switch (controlType.Name)
{
case "CheckBox":
if ((bool)controlType.GetProperty("Checked").GetValue(control,null))
controlType.GetProperty("Name").SetValue(control,"Check1",null);
break;
case "TextBox":
//TODO
break;
case "ComboBox":
//TODO
break;
default:
break;
}
}
}