C# 创建ASP.NET控件对象的副本
我在asp.net缓存中有一个来自UserControl的缓存控件对象。C# 创建ASP.NET控件对象的副本,c#,asp.net,C#,Asp.net,我在asp.net缓存中有一个来自UserControl的缓存控件对象。 我喜欢访问我的控件并复制它,以便在不影响基本缓存控件的情况下自由更改它。当然可以执行您要求执行的操作。这很简单。也许是这样的 private static void ChangeMyControlTextFromCache(string controlName, string newText, Panel containingPanel) { MyControl original = ViewState[contr
我喜欢访问我的控件并复制它,以便在不影响基本缓存控件的情况下自由更改它。当然可以执行您要求执行的操作。这很简单。也许是这样的
private static void ChangeMyControlTextFromCache(string controlName, string newText, Panel containingPanel)
{
MyControl original = ViewState[controlName] as MyControl;
if (original == null)
{
original = new MyControl();
ViewState[controlName] = original;
}
MyControl clone = CloneMyControl(original);
clone.Text = newText;
if (containingPanel.Children.Contains(original))
containingPanel.Children.Remove(original);
containingPanel.Children.Add(clone);
}
private static MyControl CloneMyControl(MyControl original)
{
MyControl clone = new MyControl();
clone.Text = original.Text;
clone.SomeOtherProperty = original.SomeOtherProperty;
return clone;
}
嗨
我找到了我要找的代码。
我把它放在这里也许对你也有帮助
/// <summary>
/// this method makes a copy of object as a clone function
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public static object Clone_Control(object o)
{
Type type = o.GetType();
PropertyInfo[] properties = type.GetProperties();
Object retObject = type.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, null, o, null);
foreach (PropertyInfo propertyInfo in properties)
{
if (propertyInfo.CanWrite)
{
propertyInfo.SetValue(retObject, propertyInfo.GetValue(o, null), null);
}
}
return retObject;
}
//
///此方法将对象的副本制作为克隆函数
///
///
///
公共静态对象克隆_控件(对象o)
{
Type Type=o.GetType();
PropertyInfo[]properties=type.GetProperties();
Object retObject=type.InvokeMember(“”,System.Reflection.BindingFlags.CreateInstance,null,o,null);
foreach(PropertyInfo属性中的PropertyInfo)
{
if(propertyInfo.CanWrite)
{
propertyInfo.SetValue(retObject,propertyInfo.GetValue(o,null),null);
}
}
返回对象;
}
这是另一种克隆方法,它也适用于MONO。
它克隆传递的控件及其子控件。
注意:即使尚未将克隆控件添加到任何页面,也无法将其添加到其他页面(或在以后的回发中)。它可能在Windows上工作,但在MONO上会崩溃,所以我想这通常是不应该做的
public static Control CloneControl(Control c) {
var clone = Activator.CreateInstance(c.GetType()) as Control;
if (c is HtmlControl) {
clone.ID = c.ID;
foreach (string key in ((HtmlControl)c).Attributes.Keys)
((HtmlControl)clone).Attributes.Add(key, (string)((HtmlControl)c).Attributes[key]);
}
else {
foreach (PropertyInfo p in c.GetType().GetProperties()) {
// "InnerHtml/Text" are generated on the fly, so skip them. "Page" can be ignored, because it will be set when control is added to a Page.
if (p.CanRead && p.CanWrite && p.Name != "InnerHtml" && p.Name != "InnerText" && p.Name != "Page") {
try {
p.SetValue(clone, p.GetValue(c, p.GetIndexParameters()), p.GetIndexParameters());
}
catch {
}
}
}
}
for (int i = 0; i < c.Controls.Count; ++i)
clone.Controls.Add(CloneControl(c.Controls[i]));
return clone;
}
公共静态控制CloneControl(控制c){
var clone=Activator.CreateInstance(c.GetType())作为控件;
如果(c是HtmlControl){
clone.ID=c.ID;
foreach(字符串输入((HtmlControl)c).Attributes.Keys)
((HtmlControl)clone.Attributes.Add(key,(string)((HtmlControl)c).Attributes[key]);
}
否则{
foreach(c.GetType().GetProperties()中的PropertyInfo p){
//“InnerHtml/Text”是动态生成的,因此跳过它们。“Page”可以忽略,因为它将在控件添加到页面时设置。
if(p.CanRead&&p.CanWrite&&p.Name!=“InnerHtml”&&p.Name!=“InnerText”&&p.Name!=“Page”){
试一试{
p、 SetValue(克隆,p.GetValue(c,p.GetIndexParameters()),p.GetIndexParameters());
}
抓住{
}
}
}
}
对于(int i=0;i
尝试此页面,包括LiteralControl和ResourceBasedLiteralControl
public static System.Web.UI.Control CloneControl(Control c)
{
Type type = c.GetType();
var clone = (0 == type.GetConstructors().Length) ? new Control() : Activator.CreateInstance(type) as Control;
if (c is HtmlControl)
{
clone.ID = c.ID;
AttributeCollection attributeCollection = ((HtmlControl)c).Attributes;
System.Collections.ICollection keys = attributeCollection.Keys;
foreach (string key in keys)
{
((HtmlControl)c).Attributes.Add(key, (string)attributeCollection[key]);
}
}else if(c is System.Web.UI.LiteralControl){
clone = new System.Web.UI.LiteralControl(((System.Web.UI.LiteralControl)(c)).Text);
}
else
{
PropertyInfo[] properties = c.GetType().GetProperties();
foreach (PropertyInfo p in properties)
{
// "InnerHtml/Text" are generated on the fly, so skip them. "Page" can be ignored, because it will be set when control is added to a Page.
if (p.Name != "InnerHtml" && p.Name != "InnerText" && p.Name != "Page" && p.CanRead && p.CanWrite)
{
try
{
ParameterInfo[] indexParameters = p.GetIndexParameters();
p.SetValue(clone, p.GetValue(c, indexParameters), indexParameters);
}
catch
{
}
}
}
}
int cControlsCount = c.Controls.Count;
for (int i = 0; i < cControlsCount; ++i)
{
clone.Controls.Add(CloneControl(c.Controls[i]));
}
return clone;
}
public static System.Web.UI.Control CloneControl(控件c)
{
Type Type=c.GetType();
var clone=(0==type.GetConstructors().Length)?新控件():Activator.CreateInstance(type)作为控件;
如果(c是HtmlControl)
{
clone.ID=c.ID;
AttributeCollection AttributeCollection=((HtmlControl)c).Attributes;
System.Collections.ICollection keys=attributeCollection.keys;
foreach(字符串键入键)
{
((HtmlControl)c).Attributes.Add(key,(string)attributeCollection[key]);
}
}else if(c是System.Web.UI.LiteralControl){
clone=newsystem.Web.UI.LiteralControl(((System.Web.UI.LiteralControl)(c)).Text);
}
其他的
{
PropertyInfo[]properties=c.GetType().GetProperties();
foreach(PropertyInfo p in properties)
{
//“InnerHtml/Text”是动态生成的,因此跳过它们。“Page”可以忽略,因为它将在控件添加到页面时设置。
if(p.Name!=“InnerHtml”&&p.Name!=“InnerText”&&p.Name!=“Page”&&p.CanRead&&p.CanWrite)
{
尝试
{
ParameterInfo[]indexParameters=p.GetIndexParameters();
p、 SetValue(克隆,p.GetValue(c,indexParameters),indexParameters);
}
抓住
{
}
}
}
}
int cControlsCount=c.Controls.Count;
对于(int i=0;i
参考:
投票结果对我来说不合适。下面是我创建ASP.NET控件对象副本的解决方案
// Copies the custom properties on the control. To use it, cast your object to it.
public static object CopyUserControl(object obj, object obj2)
{
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();
Type type2 = obj2.GetType();
PropertyInfo[] properties2 = type.GetProperties();
foreach (PropertyInfo property in properties)
{
foreach (PropertyInfo property2 in properties2)
{
// Match the loops and ensure it's not a non-custom property
if (property.Name == property2.Name && property.SetMethod != null && !property.SetMethod.IsSecuritySafeCritical)
property2.SetValue(obj2, property.GetValue(obj, null));
}
}
return obj2;
}
当您必须使用不同的html id在同一页面上复制ASCX控件时,此功能非常有用。用法:
// Copying myAscxControl1 onto myAscxControl2
myAscxControl2 = (ObjectNameToBeCasted)CopyUserControl(myAscxControl1, myAscxControl2);
它也应该适用于不同类型的对象。但要复制的属性名称必须匹配 你能发布一些控件/缓存代码吗?我认为没有克隆命令,因为每个控件都可以有子控件,它们也可以,等等。你需要多少“保真度”?不久前,我将整个(可定制的)UI“序列化”,并在以后恢复它(它是WinForms,不是ASP,但概念是相同的)。另外,您对控制的了解程度如何?如果它有一个已知的类型,您可以创建一个新实例并复制您需要的每个字段/属性。否则,反射可能会有所帮助,但在我引导您完成该方法之前,您应该提供更多详细信息。为什么要缓存控件?您正在尝试缓存其中的数据吗?你们想实现什么?嗨,朋友们,我从文件(Page.LoadControl(“ascx file name”))加载一个用户控件,这是一个耗时的过程,我喜欢将加载的用户控件缓存在缓存中,以防止从文件加载它,但是这个缓存控件在不同的地方使用,设置不同,我想在不同的地方制作不同的副本