PDA

View Full Version : کپی کردن کامل یک کنترل به وسیله ی کد نویسی



amirrr3
دوشنبه 21 فروردین 1391, 19:32 عصر
سلام دوستان
وقتی می خوام یه فرم رو دیزاین کنم مثلا اگه یه پنل با مخفلاتش رو کپی کنم، به راحتی می تونم جای دیگه پیست کنم و حتی کنترل های دیگری که تو پنل هست هم کپی می شن
می خواستم بپرسم راهی هست که این کار را با کد نویسی انجام بدم
مثلا یه پنل دارم که داخلش چند تا تکس باکس هست، می خوام با کد نویسی این پنل رو به تعدادی کپی (یا کلون) کنم
امیدوارم منظورم رو متوجه شده باشید :متفکر:

hakim22
دوشنبه 21 فروردین 1391, 19:56 عصر
کنترل ها هم یک کلاس هستند و با متد new میتونید اونها رو به تعداد دلخواه از درون کد بسازید

amirrr3
دوشنبه 21 فروردین 1391, 20:17 عصر
دوست عزیز اینو میدونم
من می خوام کنترلی که روش تغییرات دادم و روی فرم هست رو کپی کنم
مثل کپی پیست

mostafah110
دوشنبه 21 فروردین 1391, 20:27 عصر
خوب آره از دستور CONTROL.CLONE() استفاده کن!!

amirrr3
سه شنبه 22 فروردین 1391, 14:29 عصر
خوب آره از دستور CONTROL.CLONE() استفاده کن!!
میشه یکم بیشتر توضیح بدید؟
ممنون

mostafah110
سه شنبه 22 فروردین 1391, 15:18 عصر
میشه یکم بیشتر توضیح بدید؟
ممنون

من یه نگاهی که انداختم متوجه شدم، دستور clone برای کنترل ها وجود نداره، حالا برای این که یک کاری شبیه به اون بتونیم انجام بدیم دو راه داریم:
۱- استفاده از اینترفیس ICloneable که می تونیم برای اون یه پیاده سازی درست بکنیم
۲- یا این که از کلاس زیر استفاده کنیم:

/// <summary>
/// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
///
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>

public static class ObjectCopier
{
/// <summary>
/// Perform a deep Copy of the object.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T Clone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}

// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}

IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
}

کلاسم که استاتیک هست، پس به راحتی می تونی ازش استفاده کنی.

من راه دوم رو پیشنهاد می کنم.

amirrr3
چهارشنبه 23 فروردین 1391, 16:39 عصر
ببخشید دوستان
کسی تا حالا با این کلاس کار کرده؟
من که موفق نشدم باهاش آبجکت کپی کنم
اگه میشه کمک کنید . ممنون

mostafah110
چهارشنبه 23 فروردین 1391, 20:55 عصر
سلام، من یک کلاس دیگه و راحت تر از سایت code project پیدا کردم، که کار باهاش راحت تره.
لینک: http://www.codeproject.com/Articles/12976/How-to-Clone-Serialize-Copy-Paste-a-Windows-Forms

اینم خود کلاسش:

using System;
using System.Windows.Forms;
using System.Reflection;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace CtrlCloneTst
{
#region ControlFactory
/// <summary>
/// Summary description for FormControlFactory.
/// </summary>
public class ControlFactory
{
public ControlFactory()
{
//
// TODO: Add constructor logic here
//
}

public static Control CreateControl(string ctrlName,string partialName)
{
try
{
Control ctrl;
switch(ctrlName)
{
case "Label":
ctrl = new Label();
break;
case "TextBox":
ctrl = new TextBox();
break;
case "PictureBox":
ctrl = new PictureBox();
break;
case "ListView":
ctrl = new ListView();
break;
case "ComboBox":
ctrl = new ComboBox();
break;
case "Button":
ctrl = new Button();
break;
case "CheckBox":
ctrl = new CheckBox();
break;
case "MonthCalender":
ctrl = new MonthCalendar();
break;
case "DateTimePicker":
ctrl = new DateTimePicker();
break;
default:
Assembly controlAsm = Assembly.LoadWithPartialName(partialName);
Type controlType = controlAsm.GetType(partialName + "." + ctrlName);
ctrl = (Control)Activator.CreateInstance(controlType);
break;

}
return ctrl;

}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine("create control failed:" + ex.Message);
return new Control();
}
}

public static void SetControlProperties(Control ctrl,Hashtable propertyList)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(ctrl);

foreach (PropertyDescriptor myProperty in properties)
{
if(propertyList.Contains(myProperty.Name))
{
Object obj = propertyList[myProperty.Name];
try
{
myProperty.SetValue(ctrl,obj);
}
catch(Exception ex)
{
//do nothing, just continue
System.Diagnostics.Trace.WriteLine(ex.Message);
}

}

}

}

public static Control CloneCtrl(Control ctrl)
{

CBFormCtrl cbCtrl = new CBFormCtrl(ctrl);
Control newCtrl = ControlFactory.CreateControl(cbCtrl.CtrlName,cbCtr l.PartialName);

ControlFactory.SetControlProperties(newCtrl,cbCtrl .PropertyList);

return newCtrl;
}

public static void CopyCtrl2ClipBoard(Control ctrl)
{
CBFormCtrl cbCtrl = new CBFormCtrl(ctrl);
IDataObject ido = new DataObject();

ido.SetData(CBFormCtrl.Format.Name,true,cbCtrl);
Clipboard.SetDataObject(ido,false);

}

public static Control GetCtrlFromClipBoard()
{
Control ctrl = new Control();

IDataObject ido = Clipboard.GetDataObject();
if(ido.GetDataPresent(CBFormCtrl.Format.Name))
{
CBFormCtrl cbCtrl = ido.GetData(CBFormCtrl.Format.Name) as CBFormCtrl;

ctrl = ControlFactory.CreateControl(cbCtrl.CtrlName,cbCtr l.PartialName);
ControlFactory.SetControlProperties(ctrl,cbCtrl.Pr opertyList);

}
return ctrl;
}


}

#endregion

#region Clipboard Support
/// <summary>
/// Summary description for CBFormCtrl.
/// </summary>
[Serializable()]
public class CBFormCtrl//clipboard form control
{
private static DataFormats.Format format;
private string ctrlName;
private string partialName;
private Hashtable propertyList = new Hashtable();

static CBFormCtrl()
{
// Registers a new data format with the windows Clipboard
format = DataFormats.GetFormat(typeof(CBFormCtrl).FullName) ;
}

public static DataFormats.Format Format
{
get
{
return format;
}
}
public string CtrlName
{
get
{
return ctrlName;
}
set
{
ctrlName = value;
}
}

public string PartialName
{
get
{
return partialName;
}
set
{
partialName = value;
}
}

public Hashtable PropertyList
{
get
{
return propertyList;
}

}


public CBFormCtrl()
{

}

public CBFormCtrl(Control ctrl)
{
CtrlName = ctrl.GetType().Name;
PartialName = ctrl.GetType().Namespace;

PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(ctrl);

foreach (PropertyDescriptor myProperty in properties)
{
try
{
if(myProperty.PropertyType.IsSerializable)
propertyList.Add(myProperty.Name,myProperty.GetVal ue(ctrl));
}
catch(Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
//do nothing, just continue
}

}

}


}
#endregion
}



منم این طوری از کلاس استفاده کردم.


foreach (Control c in panel1.Controls)
{
panel2.Controls.Add(ControlFactory.CloneCtrl(c));
}


هرچی کنترل توی پنل ۱ هست به پنل ۲ کپی می کنم.

یا علی

amirrr3
شنبه 26 فروردین 1391, 19:21 عصر
ممنون آقا مصطفی واقعا کلاس خوبیه
بدون هیچ مشکلی کنترل ها رو کپی می کنه

ببخشید که اسپم دادم فقط خواستم بگم که جواب داد