对于Web用户控件,我需要有两个完全不同的布局,但非常重要的是,控件的代码后面保持相同。
对于两个不同的Web用户控件,我是否可以使用相同的代码?我尝试将Page指令更改为使用同一个类,但有时在构建时,会生成带有重复控件的.designer.cs
文件,从而得到编译错误。
我也尝试从一个公共基类继承,但是您看不到这个类中的任何控件,这使得采用这种方法非常困难。
还是有一种方法可以防止designer.cs类为“克隆”控件重新生成?
发布于 2015-01-06 04:23:07
我刚刚在2012年对此进行了测试。
.ascx.cs
和.ascx.Designer.cs
文件CodeBehind
和Inherits
属性进行第二次控制的修改的Inherits
指令。不需要为第二个控件生成设计器文件。而且它是有效的。我不知道这是不是有效的方法。我已经通过在每个控件中添加一个Label
并在后面的代码中设置它的值来测试它。该值反映在两个控件中。
当您在一个用户控件中有一个asp.net控件而在另一个用户控件中不存在时,您可能会遇到问题。
发布于 2015-01-06 04:06:51
创建基类,并在那里实现公共逻辑。然后从这个基类继承控件。为了从基类级别访问控件,为您需要的每个控件在基类级别上设置抽象的get属性。在子控件类中实现这些属性。
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";
}
}
发布于 2015-01-06 04:27:49
除了@Ondrej的正确答案之外,我建议您查看一下MVP设计模式,并可能将其与您的works代码一起使用。它有效,我在一个大型项目中尝试过它,其结果不亚于MVC项目中的关注点分离。有一些框架可以帮助您实现它,但出于某种原因,我更喜欢自己实现它(毕竟,它是两个基类和一个基本接口)。
https://stackoverflow.com/questions/27798144
复制