3

我是第一次编写一些用户控件,我想知道是否有办法清理我的一些代码。(如果您想了解我正在研究的更多背景信息,请参阅此问题。)

我有一个BaseControl类,基本上,它解析一些 XML 数据,然后根据该数据中包含的内容,调用适当UserControl的并在其途中发送数据。这是一个例子:

public partial class BaseControl : User Control
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ... //code that parses the data
        var renewalDef = effort.Attributes["renewal_def"].Value;
        var effortNumber = effort.Attributes["renewal_effort_number"].Value;
        if (effortNumber == "1")
        {
            var effortControl = (NAVLEffort1) Page.LoadControl("~/NAVLSeriesControls/NAVLEffort1.ascx");
            effortControl.transactionData = transaction; //'transaction' is a Hashtable object
            HtmlContent.Controls.Add(effortControl); //'HtmlContent' is a PlaceHolder control on BaseControl.ascx page
        }
        if (effortNumber == "2")
        {
            var effortControl = (NAVLEffort2) Page.LoadControl("~/NAVLSeriesControls/NAVLEffort2.ascx");
            effortControl.transactionData = transaction; //'transaction' is a Hashtable object
            HtmlContent.Controls.Add(effortControl); //'HtmlContent' is a PlaceHolder control on BaseControl.ascx page
        }
        if (effortNumber == "3")
        {
            var effortControl = (NAVLEffort3) Page.LoadControl("~/NAVLSeriesControls/NAVLEffort3.ascx");
            effortControl.transactionData = transaction; //'transaction' is a Hashtable object
            HtmlContent.Controls.Add(effortControl); //'HtmlContent' is a PlaceHolder control on BaseControl.ascx page
        }
        // and so on...
    }
}

这不是我写的实际代码,它只是我可以前进的一个例子。我想做的是更像这样的事情:

...
var effortControlFileString = string.Format("~/NAVLSeriesControls/{0}Effort{1}.ascx", renewalDef, effortNumber);
var effortControl = (renewalDef + "Effort" + effortNumber) Page.LoadControl(effortControlFileString);
effortControl.transactionData = transaction;
HtmlContent.Controls.Add(effortControl)
...

有什么想法可以清理这个烂摊子吗?

4

2 回答 2

5

界面

您可以让所有控件实现一个通用接口并转换为该接口。

public interface IMyInterface
{
    object TransactionData
    {
       get;
       set;
    }
}

Control effortControl = Page.LoadControl(path);
HtmlContent.Controls.Add(effortControl);

IMyInterface obj = (IMyInterface)effortControl;
obj.TransactionData = transaction;

在在线 IDE 中查看此工作示例。

基类

您还可以使用抽象基类并转换为具有相同结果的该类型。您将需要使用继承自UserControl. 这将避免有两个对象引用(如我上面的示例),因为它可以强制转换为UserControl.

上面的例子变成:

MyCustomControlType c = (MyCustomControlType)Page.LoadControl(path);
HtmlContent.Controls.Add(c);
c.TransactionData = transaction;

如果每种控件类型的逻辑不同,那么您可能需要转换为每种特定类型(基本上是一个大的 if/else 块)并单独处理每个控件。换句话说,如果您需要根据控件的类型执行不同的操作,您将需要类型感知的逻辑。

为了完整起见,我会提到你也可以使用DLR,但我建议不要这样做。您将放弃编译时类型安全性和性能以减少一些代码。

于 2012-04-06T21:18:01.373 回答
0

您可以创建一个界面并将您的控件添加到 html 页面。前任:

private Control _contentControl;

_contentControl = Page.LoadControl("~/Administration/Projects/UserControls/" + controlName);
        ((IEditProjectControl)_contentControl).ProjectId = ProjectId;
        plhContent.Controls.Clear();
        plhContent.Controls.Add( _contentControl );
        _contentControl.ID = "ctlContent";
        Image2.Visible = ((IEditProjectControl)_contentControl).ShowSaveButton;
        SaveButton.Visible = ((IEditProjectControl)_contentControl).ShowSaveButton;
        ((IEditProjectControl)_contentControl).Initialize();
于 2014-06-03T13:41:50.770 回答