我想编写一个方法,用于从另一个线程中使用,以更改多个button
s textBox
es等中的文本和颜色。
我希望它像
public void ChangeUIPropertys(Object UIObject , Color color , string Text , ... )
{
switch (UIObject.GetType)
{
//switch cases
//...
//...
case Textbox :
{
//put here correct method with Invoke for correct cross Thread behavior
//DoSomething
}
}
}
实现类似的东西的正确方法是什么?
答案 0 :(得分:3)
很明显Object UIObject
是Control,所以方法的定义可以改变,如
public void ChangeUIPropertys(Control UIObject , Color color , string Text)
{
// to check control type
if (control is TextBox)
{
var tb = (TextBox)control;
// apply changes
}
else if (control is Label)
{
// do the same
}
}
以线程安全的方式
public void ChangeUIPropertys(Control UIObject , Color color , string Text)
{
// to make whole operation thread safe
var action = delegate {
// to check control type
if (control is TextBox)
{
var tb = (TextBox)control;
// apply changes
}
else if (control is Label)
{
// do the same
}
};
if (control.InvokeRequired)
control.Invoke(action);
else
action.Invoke();
}
答案 1 :(得分:2)
你不能使用switch
。您应该使用if
,可能:
if (UIObject is TextBox)
{
// use UIObject
}
或者,如果您想将UIObject
重新用作TextBox
:
TextBox tb = UIObject as TextBox;
if (tb != null)
{
// use tb
}
如果从另一个线程调用,请确保在对象上使用Invoke
以使用正确的线程。
答案 2 :(得分:2)
您可以将用作运算符:
TextBox textBox = UIObject as TextBox;
if (null != textBox) {
// Do what you want with the textBox
}
如果您想更改Text
和Color
,只能使用抽象 控制 类:
Control ctrl = UIObject as Control;
// Both Button and TextBox
if (null != ctrl) {
ctrl.BackColor = Color.Red;
ctrl.Text = "My Text";
}
答案 3 :(得分:1)
由于Control
基类实现了Text
以及您提到的其他属性,您可以使用
foreach(var control in this.Controls.OfType<Control>())
control.Text = "new text";
注意:这假设是Windows窗体,但此答案的其他版本可用
答案 4 :(得分:1)
虽然可以在这里处理case
语句来处理调度(demo)但它不可靠。使用基于typeof
的条件链也是如此。
更好的选择是使用内置的调度机制dynamic
:
public void ChangeUIPropertys(dynamic UIObject, Color color , string Text , ... ) {
// ^^^^^^^
ChangeUiPropertyImpl(UIObject, color, text);
}
private void ChangeUIPropertysImpl(Textbox tb, Color color , string Text , ...) {
tb.SetColor(color);
}
private void ChangeUIPropertysImpl(Label lbl, Color color , string Text , ...) {
lbl.SetColor(color);
}
一旦告诉C#UIObject
是dynamic
,它会在运行时找到ChangeUIPropertysImpl
方法的最佳拟合覆盖。这为switch
语句提供了一种非常快速的替代方法。
答案 5 :(得分:1)
这可能是replace the conditional with polymorphism的好机会。您可以定义一个抽象对象,例如:
abstract class UIObject
{
abstract public void ChangeColor(Color color);
// other operations
}
对于可以在其上执行此操作的每个UI元素,您可以定义具体实现:
class TextBoxObject : UIObject
{
private TextBox uiElement;
public TextBoxObject(TextBox textBox)
{
uiElement = textBox;
}
override public void ChangeColor(Color color)
{
// change the color of the text box
}
// other operations
}
然后消费代码将在抽象上运行,而不是(可能发生变化的)一组实现:
public void ChangeUIProperties(UIObject uiObject, Color color, string Text, ... )
{
uiObject.ChangeColor(color);
// other operations
}
这将是一种更加面向对象的方法,将特定于实现的功能封装到多态对象中,而不是长条件表达式。从消费代码的角度来看,类型本质上并不重要,实现细节被封装在抽象之后。
答案 6 :(得分:0)
获得对象的类型后,只需将其与typeof(Textbox)
等进行比较。
答案 7 :(得分:0)
你可以这样做以避免2个cas(1个用于IS,1个用于使用控件):
var textbox = UIObject as Textbox;
if(textbox != null)
{
// change color
}
var button = UIObject as Button;
if(button != null)
{
// change color
}