【发布时间】:2014-10-21 01:27:24
【问题描述】:
我需要使用文字字符串名称将不同的对象转换为不同的类型。一些示例代码:
string controlName = "Control";
string stringName = "string";
string panelName = "Panel";
var x = Panel();
((Control)x).Name = "SomeName";
上面的代码当然可以,但不是这一行
((Control)x).Name = "Normal";
如何使用线路
((controlName)x).Name = "Awesome";
我希望这是有道理的,但如果我需要进一步解释,我可以尝试。
我正在创建一系列在 xml 模式中定义的问题。问题会有所不同,例如 1. 这是什么时候发生的。 2 为什么会这样。 3.这是什么类型(type 1,type 2, type3)
所有这些都由一个基本控件读取。 1 需要答案控件作为日期时间选择器,2 需要文本框,3 需要组合框。
我会订阅文本框的 textchange 事件、datetimepicker 的值更改事件和组合框的 selectedindexchange 事件。
这过于简单化了,我实际上在做的是控制和创建事件。
我现在处理它的方式是一个巨大的案例陈述。我想知道是否有更简单的方法可以将控件转换为 xml 文档中定义的类型(字符串值)
编辑*
要求的代码
namespace ScriptControl
{
public partial class ScriptItem
{
public FollowupEvent ActiveEvent{get;set;}
public event EventHandler AnswerChanged;
#region Constructors
public ScriptItem()
{
}
public ScriptItem(DataRow row)
{
}
public ScriptItem(XElement xelem,FollowupEvent activeEvent,int instanceID)
{
ActiveEvent = activeEvent;
InstanceID = instanceID;
try
{
Question = xelem.Elements("Text").First().Value.ToString();
AnswerType = xelem.Elements("Type").First().Value.ToString();
ControlType = xelem.Elements("Control").First().Attribute("Type").Value.ToString();
ActivityID = Convert.ToInt32(xelem.Attribute("ID").Value.ToString());
ScriptItemType = xelem.Elements("ScriptItemType").First().Value.ToString();
ScriptItemQuestionType = xelem.Elements("QuestionType").First().Value.ToString();
InputControl = ConfigureInputControl(xelem.Elements("Control").First().Attribute("Type").Value.ToString());
QuestionControl = ConfigureQuestionControl(xelem.Elements("Control").First().Attribute("Type").Value.ToString());
Prompt = xelem.Elements("Prompt").First().Value.ToString();
}
catch { }
}
#endregion
#region Public Properties
public string Prompt { get; set; }
public Panel QuestionPanel = new Panel();
public int ActivityID { get; set; }
public string Question { get; set; }
public string AnswerType { get; set; }
public object Result { get; set; }
public Control InputControl { get; set; }
public string ControlType { get; set; }
public Control QuestionControl { get; set; }
public string ScriptItemType { get; set; }
public string ScriptItemQuestionType { get; set; }
public int InstanceID { get; set; }
public ScriptControl.Entities.ScriptControlBase ScriptBaseControl { get; set; }
#endregion
public Control ConfigureInputControl(string controlType)
{
switch (controlType)
{
case "Checkbox":
InputControl = new CheckBox();
break;
case "BooleanQuestion":
InputControl = new BooleanQuestion();
((BooleanQuestion)InputControl).AnswerChanged += ScriptItem_AnswerChanged;
((BooleanQuestion)InputControl).SetQuestion(Question);
break;
case "TextBox":
InputControl = new TextBox();
((TextBox)InputControl).KeyDown += ScriptItem_AnswerChanged;
break;
case "RadioButton":
InputControl = new RadioButton();
break;
case "DropDown":
InputControl = new RadioButton();
break;
case "DateTimePicker":
InputControl = new DateTimePicker();
((DateTimePicker)InputControl).KeyDown += ScriptItem_AnswerChanged;
break;
case ".CustomControls.SmartParts.CauseForRepair":
case".CustomControls.SmartParts.Airlines":
case ".CustomControls.SmartParts.DREntry":
InputControl = GetUIControl();
((FN_ControlBase)InputControl).PropertyChanged += ScriptItem_AnswerChanged;
break;
}
return InputControl;
}
private void ScriptItem_AnswerChanged(object sender, EventArgs e)
{
Dictionary<string, object> workFlowParams = new Dictionary<string, object>();
switch (ControlType)
{
case "BooleanQuestion":
Control x = ((Control)sender).Parent.Parent.Parent;
Result = ((BooleanQuestion)x).Answer;
workFlowParams.Add("QuestionID",Activity);
workFlowParams.Add("InstanceID", InstanceID);
workFlowParams.Add("Result",Result);
break;
case "TextBox":
if (((KeyEventArgs)e).KeyValue == 13)
{
Result = ((TextBox)sender).Text;
workFlowParams.Add("QuestionID", Activity);
workFlowParams.Add("InstanceID", InstanceID);
workFlowParams.Add("Result", Result);
}
break;
case "DateTimePicker":
if (((KeyEventArgs)e).KeyValue == 13)
{
Result = ((DateTimePicker)sender).Text;
workFlowParams.Add("QuestionID", Activity);
workFlowParams.Add("InstanceID", InstanceID);
workFlowParams.Add("Result", Result);
}
break;
case ".CustomControls.SmartParts.Airlines":
case ".CustomControls.SmartParts.CauseForRepairUI":
case ".CustomControls.SmartParts.CancelCallUI":
case ".CustomControls.SmartParts.CostCenter":
case ".CustomControls.SmartParts.ReadyToBill":
case ".CustomControls.SmartParts.TemporaryFix":
case ".CustomControls.SmartParts.BrakeRepairFollowup":
case ".CustomControls.SmartParts.DREntry":
default:
if (((PropertyChangedEventArgs)e).PropertyName == "WorkComplete" & Convert.ToBoolean(((.CustomControls.FN_ControlBase)sender).GetPropertyValue("WorkComplete")) == true)
{
foreach (var propty in ((.CustomControls.FN_ControlBase)sender).GetType().GetProperties())
{
if (ActiveEvent.HasProperty(propty.Name) & propty.Name != "EventID")
{
ActiveEvent.SetPropertyValue(propty.Name, ((Control)sender).GetPropertyValue(propty.Name));
}
}
}
workFlowParams.Add("QuestionID", Activity);
workFlowParams.Add("InstanceID", InstanceID);
workFlowParams.Add("Result", ActiveEvent);
break;
}
AnswerChanged(workFlowParams, e);
}
public Control ConfigureQuestionControl(string controlType)
{
switch (controlType)
{
case "BooleanQuestion":
((BooleanQuestion)InputControl).SetQuestion(Question);
break;
case "TextBox":
QuestionControl = new Label { Visible = true, Location = new Point(0, 0), Text = Question};
break;
case "DateTimePicker":
QuestionControl = new Label { Visible = true, Location = new Point(0, 0), Text = Question};
break;
}
return QuestionControl;
}
public Control ConfigureControl()
{
var height = 0;
var width = 0;
ScriptBaseControl = new ScriptControl.Entities.ScriptControlBase();
if (InputControl is BooleanQuestion || ScriptItemType == "Control")
{
InputControl = ConfigureInputControl(ControlType);
ScriptBaseControl.AddControl(InputControl);
ScriptBaseControl.SetPrompt(Prompt);
foreach (Control c in ScriptBaseControl.FilterControls(ctl => !(ctl is Panel) && !(ctl is FlowLayoutPanel) && !(ctl is GroupBox) && !(ctl is ScriptControlBase)))
{
height = height + c.Height;
if (c.Width > width)
{
width = c.Width;
}
}
ScriptBaseControl.Size = new Size(width, height);
}
else
{
FlowLayoutPanel x = new FlowLayoutPanel();
x.Controls.Add(QuestionControl);
x.Controls.Add(InputControl);
foreach (Control c in ScriptBaseControl.FilterControls(ctl => !(ctl is Panel) && !(ctl is FlowLayoutPanel) && !(ctl is GroupBox) && !(ctl is ScriptControlBase)))
{
height = height + c.Height;
if (c.Width > width)
{
width = c.Width;
}
}
x.Size = new Size(width, height);
ScriptBaseControl.Size = x.Size;
ScriptBaseControl.AddControl(x);
ScriptBaseControl.SetPrompt(Prompt);
}
return ScriptBaseControl;
}
private Control GetUIControl()
{
Control uiControl = new Control();
switch (ControlType)
{
case ".CustomControls.SmartParts.Air":
uiControl = new .CustomControls.SmartParts.Airlines(ActiveEvent.EventID) { ExternalSave = true};
break;
case ".CustomControls.SmartParts.CauseFor":
uiControl = new .CustomControls.SmartParts.CauseForRepairUI() { ExternalSave = true };
break;
case ".CustomControls.SmartParts.Cancel":
uiControl = new .CustomControls.SmartParts.CancelCallUI() { ExternalSave = true,EventID = ActiveEvent.EventID };
break;
case ".CustomControls.SmartParts.Cost":
uiControl = new .CustomControls.SmartParts.CostCenter() { ExternalSave = true};
break;
case ".CustomControls.SmartParts.ReadyTo":
uiControl = new .CustomControls.SmartParts.ReadyToBill(ActiveEvent.EventID) { ExternalSave = true, EventID = ActiveEvent.EventID };
break;
case ".CustomControls.SmartParts.Temporary":
uiControl = new .CustomControls.SmartParts.TemporaryFix() { ExternalSave = true};
break;
case ".CustomControls.SmartParts.RepairFollowup":
uiControl = new .CustomControls.SmartParts.BrakeRepairFollowup() { ExternalSave = true, EventID = ActiveEvent.EventID};
break;
case ".CustomControls.SmartParts.Entry":
uiControl = new .CustomControls.SmartParts.DREntry() { ExternalSave = true };
break;
}
return uiControl;
}
}
}
【问题讨论】:
-
您是否尝试将变量转换为名称在另一个字符串变量中动态设置的类?你为什么需要那个?可能有一种更简单的方法来实现您真正想要做的事情。
-
不,你不能那样做。
-
请注意,您可以从该字符串中获得的只是一个
Type对象,并且您不能像在副本中讨论的那样从中进行转换。 -
...并且您不需要转换,因为类型是推断出来的。
-
您正在尝试做的事情不称为强制转换。您正在尝试访问名为
Name的Property类ControlName。这被称为Reflection,它的 $%&* 非常痛苦。或者,您可以使用duck-typing,这可以通过转换为dynamic类型来完成。但是,如果对象实现了多个Name属性,这将无济于事。
标签: c# casting object-type