我可以有两个Web用户控件(.ascx)共享相同的代码隐藏类吗?

时间:2015-01-06 11:54:43

标签: c# asp.net webusercontrol

我有一种情况,我需要为Web用户控件提供两种完全不同的布局,但控件的代码隐藏保持相同非常重要。

有什么方法可以为两个不同的Web用户控件使用相同的代码隐藏?我已经尝试更改Page指令以使用相同的类,但有时在构建时,生成.designer.cs文件时会出现重复控件,因此会出现编译错误。

我也尝试从公共基类继承,但是你看不到这个类的任何控件,这使得采用这种方法变得非常困难。

或者有没有办法阻止为“克隆”控件重新生成designer.cs类?

3 个答案:

答案 0 :(得分:2)

创建基类,并在那里实现通用逻辑。然后从此基类继承控件。要从基类级别访问控件,请在基类级别为所需的每个控件创建抽象获取属性。在子控件类中实现这些属性。

public abstract class BaseControl : UserControl
{
  public abstract TextBox FirstName { get; }

  public void SomeLogicExample() 
  {
    FirstName.Text = "Something"; 
  }
}

public class ControlA : BaseControl
{
  public override TextBox FirstName
  {
    // txtFirstNameA is ID of TextBox, so it is defined in ControlA.designer.cs
    get { return txtFirstNameA; }
  }
}

public class ControlB : BaseControl
{
  public override TextBox FirstName
  {
    // txtFirstNameB is ID of TextBox, so it is defined in ControlB.designer.cs
    get { return txtFirstNameB; }
  }
}

另外,优雅的是在运行时定位控件;因为你付费搜索整个控制树而你必须处理未找到控件的情况:

public abstract class BaseControl : UserControl
{
  public T GetControlByType<T>(Func<T, bool> predicate = null) where T : Control
  {
    var stack = new Stack<Control>(new Control[] { this });
    while (stack.Count > 0)
    {
      var control = stack.Pop();
      T match = control as T;
      if (match != null)
      {
        if (predicate == null || predicate(match))
        {
          return match;
        }
      }

      foreach (Control childControl in control.Controls)
      {
        stack.Push(childControl);
      }
    }

    return default(T);
  }    

  public TextBox FirstName
  {
    get { return GetControlByType<TextBox>(t => t.ID == "txtFirstName"); }
  }

  public void SomeLogicExample() 
  {
    FirstName.Text = "Something"; 
  }
}

答案 1 :(得分:2)

我刚刚在VS 2012中对此进行了测试。

  1. 我添加了2个用户控件
  2. 从第二个控件中删除了.ascx.cs.ascx.Designer.cs文件
  3. PageCodeBehind属性的第二个控件的修改Inherits指令。无需为第二个控件生成Designer文件。
  4. 它有效。我不知道这是否有效。 我通过在每个控件中添加Label并在后面的代码中设置其值来测试它。该值反映在两个控件中。

    如果在一个用户控件中有一个asp.net控件,而在另一个用户控件中不存在,则可能会遇到问题。

答案 2 :(得分:1)

除了@Ondrej Svejdar的正确答案之外,我建议您查看MVP design pattern并将其与您的Web窗体代码一起使用。它有效,我在一个大项目中尝试过,结果并不比MVC项目中的关注点分离更糟糕。有一些框架可以帮助你实现它,但由于某种原因,我更喜欢自己实现它(毕竟它是一些基类和一个基本接口)