例如,我有DataGridView
控件,其中包含蓝色BackgroundColor
属性等等。有没有一种方法可以将这些属性以编程方式传输或传递给另一个DataGridView
控件?
这样的事情:
dtGrid2.Property = dtGrid1.Property; // but of course, this code is not working
...谢谢
答案 0 :(得分:5)
你需要使用反射。
您获取源控件中每个属性的引用(基于其类型),然后“获取”其值 - 将该值分配给目标控件。
这是一个粗略的例子:
private void copyControl(Control sourceControl, Control targetControl)
{
// make sure these are the same
if (sourceControl.GetType() != targetControl.GetType())
{
throw new Exception("Incorrect control types");
}
foreach (PropertyInfo sourceProperty in sourceControl.GetType().GetProperties())
{
object newValue = sourceProperty.GetValue(sourceControl, null);
MethodInfo mi = sourceProperty.GetSetMethod(true);
if (mi != null)
{
sourceProperty.SetValue(targetControl, newValue, null);
}
}
}
答案 1 :(得分:3)
您可以使用反射来获取该类型的所有公共属性,并将值从一个实例复制到另一个实例,但这很危险,并且可能无法真正复制对象的整个状态。可能有一些您不想复制的属性(例如Parent,Site)以及您无法直接设置的其他重要属性(例如Columns,Rows)。此外,可能存在引用类型的属性;您复制的控件最终将引用与原始对象相同的对象,这可能是不合需要的。还可能存在只能通过方法调用设置的状态信息,这些信息不会以这种方式复制。简而言之,反思可能不是您正在寻找的解决方案。
您可能只需手动复制所需的属性即可。或者,您可以创建一个可以创建任意数量的类似网格的工厂方法。
答案 2 :(得分:2)
我在codeproject上发布了一个关于如何在几年前复制和粘贴或克隆控件的演示项目, http://www.codeproject.com/Articles/12976/How-to-Clone-Serialize-Copy-Paste-a-Windows-Forms
答案 3 :(得分:1)
这是我提出的代码。我只使用Label,TextBox,Panel和DataGridView控件进行了测试。对于Panel控件,您将获得所有包含的控件(克隆实例)。对于DataGridView控件,您将获得数据绑定,它将与绑定到源DataGridView控件的完全相同的数据。当然,如果没有绑定,那么克隆的实例将没有绑定。这些行为是否合适取决于您的需求。
private Control CloneControl(Control srcCtl)
{
var cloned = Activator.CreateInstance(srcCtl.GetType()) as Control;
var binding = BindingFlags.Public | BindingFlags.Instance;
foreach(PropertyInfo prop in srcCtl.GetType().GetProperties(binding))
{
if (IsClonable(prop))
{
object val = prop.GetValue(srcCtl);
prop.SetValue(cloned, val, null);
}
}
foreach(Control ctl in srcCtl.Controls)
{
cloned.Controls.Add(CloneControl(ctl));
}
return cloned;
}
private bool IsClonable(PropertyInfo prop)
{
var browsableAttr = prop.GetCustomAttribute(typeof(BrowsableAttribute), true) as BrowsableAttribute;
var editorBrowsableAttr = prop.GetCustomAttribute(typeof(EditorBrowsableAttribute), true) as EditorBrowsableAttribute;
return prop.CanWrite
&& (browsableAttr == null || browsableAttr.Browsable == true)
&& (editorBrowsableAttr == null || editorBrowsableAttr.State != EditorBrowsableState.Advanced);
}
答案 4 :(得分:0)
我在下面的代码中使用了复制选定的属性。
public static void CloneControl(Control SourceControl, Control DestinationControl)
{
String[] PropertiesToClone = new String[] { "Size", "Font", "Text", "Tag", "BackColor", "BorderStyle", "TextAlign", "Width", "Margin" };
PropertyInfo[] controlProperties = SourceControl.GetType().GetProperties();
foreach (String Property in PropertiesToClone)
{
PropertyInfo ObjPropertyInfo = controlProperties.First(a => a.Name == Property);
ObjPropertyInfo.SetValue(DestinationControl, ObjPropertyInfo.GetValue(SourceControl));
}
}
答案 5 :(得分:0)
基于this post这是
的版本public static class ControlExtensions
{
public static T Clone<T>(this T controlToClone) where T : Control
{
PropertyInfo[] controlProperties =
typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
//T instance = Activator.CreateInstance<T>();
Control instance = (Control) Activator.CreateInstance(controlToClone.GetType());
foreach (PropertyInfo propInfo in controlProperties)
{
if (propInfo.CanWrite)
{
if (propInfo.Name != "WindowTarget")
propInfo.SetValue(instance,
propInfo.GetValue(controlToClone, null), null);
}
}
foreach(Control ctl in controlToClone.Controls)
{
instance.Controls.Add( ctl.Clone() );
}
return (T) instance;
}
}
您仍然可能想要测试是否应过滤掉WindowTarget
以上的属性..
有趣的是:如果要克隆的控件是TabPage
,它将是不可见的..
答案 6 :(得分:0)
我用过这个:
Control NewControl=new Control(ControlToClone,ControlToClone.Name);
答案 7 :(得分:0)
在Designer中设置了所有属性之后,我想要将所有这些配置复制到另一个DataGridView中,并且遇到了相同的问题。 我通过检查InitializeComponent()解决了它;表格的一部分。 可以轻松找到我设置的所有属性,然后通过代码将其再次设置到另一个DataGridView控件。
例如,我设置了:
DataGridViewCellStyle dgvCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
dgvCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dgvCellStyle1.BackColor = System.Drawing.SystemColors.Window;
dgvCellStyle1.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dgvCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText;
dgvCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dgvCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dgvCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
dgv.DefaultCellStyle = dgvCellStyle1;
dgv.GridColor = System.Drawing.SystemColors.ControlLight;
dgv.Location = new System.Drawing.Point(258, 315);
dgv.ReadOnly = true;
dgv.RowHeadersVisible = false;
dgv.RowTemplate.Height = 18;
dgv.ShowEditingIcon = false;