作为进度条控件的一部分,我添加了一个方法来接受传递给它的任何控件,该控件将用作报告'的方法。进度或任务状态以及进度条本身上的显示:
public void SetReportObject( object obj ) {
}
我遇到的问题是,当我去设置Text值或某些控件有TextValue
时,obj
没有可用的属性,从而在IDE中生成错误,从而阻止了这一点编译。
我认为,应该实施某种typeof
,但我不确定如何解决这个问题。传递的对象可以是任何用户控件。
我在WinForms项目中使用c#。
答案 0 :(得分:2)
您可以使用反射来设置属性,而无需在编译时知道确切的类型。这样的事情会做:
public void SetReportObject( object obj )
{
if(obj == null) throw new ArgumentNullException("obj");
PropertyInfo textProperty = obj.GetType().GetProperty("Text");
if(textProperty == null) throw new InvalidOperationException("The control must have a Text property");
if(!textProperty.CanWrite) throw new InvalidOperationException("The control must have a setteable Text property");
textProperty.SetValue(obj, "0%", null);
}
我认为您至少可以将Control
作为基类参数而不是对象,但会根据您的使用情况而有所不同。我也怀疑这是不是一个好的做法,但肯定是这样做的。
答案 1 :(得分:2)
我不知道我是否理解你的问题。如果您正在处理某个不是Control的类型对象,我认为您的api需要消费者信息。
public void SetReportObject<T>(T obj, Expression<Func<T, string>> data)
{
string yourData = "Something to Notify";
var exp = data.Body as MemberExpression;
var pInfo = exp.Member as PropertyInfo;
pInfo.SetValue(obj, yourData, null);
}
按照您必须使用TextBox调用的示例:
SetReportObject<TextBox>(textBox1, x => x.Text);
答案 2 :(得分:1)
只需接受Control
作为您的类型,就会有Text
property所有控件都会实现。
public void SetReportObject( Control obj ) {
obj.Text = "This is some text";
}
但是,如果您只是用它来报告进度,我建议抽象掉控制部分,而只是使用IProgress<int>
。
public void UpdateProgress(IProgress<int> progress) {
progress.Report(_currentProgress);
}
在从非UI线程更新文本之前,这已经增加了不再需要control.Invoke
的好处。