我遇到了一个根本无法解决的问题,我已经研究了几个小时,但没有结果。请帮忙!
我想做的事:
我有一个用户控件,它在我的窗体上列出了一个类,如果有人在列表上选择了其他项,我希望它在主窗体上进行更改。
所以我创建了一个事件:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedIndex != -1)
{
Object item = this.List.GetType().GetProperty("Item").GetValue(this.List, new Object[] { listBox1.SelectedIndex });
Control a = this.TopLevelControl;
Object temp = a.GetType().GetProperty("currentExpression").GetValue( a, null );
a.GetType().GetProperty("currentExpression").SetValue(temp, item, null);
}
}
在这段代码中,"a"持有主窗体。(这个事件在用户控件中运行)所以我拥有我所需要的一切。
List对象是表达式列表。Main表单上的currentExpression属性是一个Expression。
我想把表达式(我称之为项)放在属性currentExpression(它是MainForm上的一个表达式)上。但它总是说"对象与目标类型不匹配"。TargetException未经处理
当我调试时,我可以看到它们都是正确的。(temp和item)但是它仍然抛出一个异常。
编辑:
我必须说,"List"对象不是List<Something>
,它是要列出的对象,所以List是一个对象(object List)。我的用户控件是通用的,这就是我使用反射的原因。
这样我就可以拥有objectList1.ShowList(ListExpressions,"OriginalExpression");
在这种情况下,ListExpressions是一个List,但作为对象发送给用户控件。通过反射,我可以检查它是哪种类型的List,然后读取属性"OriginalExpression"并显示列表。
所以我会有一个属性"OriginalExpression"的列表。
用户控件工作正常,问题是使最后一部分工作正常。当我点击一个项目时,我会收到消息"对象与目标类型不匹配"
有什么办法吗?
非常感谢!
为什么需要用反射来完成这一切?你什么也没说。
这看起来像是一种复杂的写作方式:
var item = this.List[listBox1.SelectedIndex];
var a = this.TopLevelControl;
var temp = a.currentExpression;
temp.currentExpression = item; // ???
除了最后一行(我标记为???
)看起来很奇怪,因为您在a
上GetType()
,从a
的类型中找到属性currentExpression
,然后使用temp
作为设置属性(设置为item
)的实例。这是我所说的你的问题中的一句话:
a.GetType().GetProperty("currentExpression").SetValue(temp, item, null);
为什么不这样实现:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if ( listBox1.SelectedIndex != -1 )
{
var item = this.List.Item[listBox1.SelectedIndex];
var mainControl = this.TopLevelControl as IExpressionProvider;
if ( mainControl != null )
mainControl.CurrentExpression = item;
}
}
在您的主窗体中,只需实现这个简单的接口:
public interface IExpressionProvider
{
YourExpressionType CurrentExpression { get; set; }
}
我解决了这个问题,
这不是我想要的,但它正在发挥作用!
我更改了
Control a = this.TopLevelControl;
至
mainForm a = (mainForm)this.TopLevelControl;
a.GetType().GetProperty("currentExpression").SetValue(temp, (NCalc.Expression)item, null);
至
a.currentExpression = ( NCalc.Expression )item;
这解决了我的问题,因为我在避免反思。谢谢大家