Можно скопировать все свойства определенного элемента управления? (Формы windows C #)

Например, у меня есть DataGridView управления DataGridView с свойством Blue BackgroundColor т. Д., Есть ли способ, которым я могу передать или передать программно эти свойства другому DataGridView управления DataGridView ?

Что-то вроде этого:

 dtGrid2.Property = dtGrid1.Property; // but of course, this code is not working 

Благодаря…

Вам нужно будет использовать reflection.

Вы получаете ссылку на каждое свойство в своем исходном элементе управления (в зависимости от его типа), затем «получаете» его значение – присваивая это значение целевому элементу управления.

Вот грубый пример:

  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); } } } 

Вы можете использовать reflection, чтобы получить все общедоступные свойства типа и скопировать значения из одного экземпляра в другой, но это опасно и не может действительно дублировать все состояние объекта. Могут быть некоторые свойства, которые вы не хотите копировать (например, Parent, Site) и другие важные свойства, которые вы не можете установить напрямую (например, столбцы, строки). Кроме того, могут быть свойства, которые являются ссылочными типами; ваш скопированный элемент управления будет ссылаться на тот же объект, что и ваш оригинал, что может быть нежелательным. Также может быть информация о состоянии, которая может быть установлена ​​только через вызовы методов, которые не будут скопированы таким образом. Короче говоря, reflection, вероятно, не является решением, которое вы ищете.

Вам просто нужно вручную скопировать нужные свойства. Кроме того, вы можете создать фабричный метод, который может создавать любое количество подобных сеток.

Я опубликовал демо-проект по codeproject о том, как копировать и вставлять или клонировать contorl несколько лет назад, http://www.codeproject.com/Articles/12976/How-to-Clone-Serialize-Copy-Paste-a-Windows- формы

Вот код, который я придумал. Я тестировал его только с помощью элементов Label, TextBox, Panel и DataGridView. Для панели управления вы получите все содержащиеся элементы управления (клонированные экземпляры). Для элемента управления 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); } 

Основываясь на этом сообщении, здесь представлена ​​версия, которая

  • создает правильные типы управления и
  • делает это рекурсивно

 public static class ControlExtensions { public static T Clone(this T controlToClone) where T : Control { PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); //T instance = Activator.CreateInstance(); 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 ) TabPage он будет невидим.

Я использовал это:

  Control NewControl=new Control(ControlToClone,ControlToClone.Name); 

I Используется под кодом для копирования выбранных свойств.

 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)); } } 
  • Вызов (делегат)
  • Как создать окно сообщения с параметрами «Да», «Нет» и «Диалоговое окно»?
  • Как вы должны диагностировать ошибку? SEHException - Внешний компонент выбрал исключение
  • ToggleButton в C # WinForms
  • Как вы не можете RichTextBox обновить его отображение?
  • Создайте BackgroundWorker, выполнив несколько операций последовательно, не замораживая форму
  • Как я могу запретить пользователю закрывать мое приложение C #?
  • Заполните панель с gradleиентом в трех цветах
  • Показать дочернюю форму в центре родительской формы в C #
  • Как сделать два прозрачных слоя с помощью c #?
  • Список vs BindingList Преимущества / Недостатки
  • Давайте будем гением компьютера.