Можно скопировать все свойства определенного элемента управления? (Формы windows C #)
Например, у меня есть DataGridView
управления DataGridView
с свойством Blue BackgroundColor
т. Д., Есть ли способ, которым я могу передать или передать программно эти свойства другому DataGridView
управления DataGridView
?
Что-то вроде этого:
dtGrid2.Property = dtGrid1.Property; // but of course, this code is not working
Благодаря…
- this.Visible не работает в Windows Forms
- Добавить таймер в приложение Windows Forms
- Введите символ «&» в текстовую метку в Windows Forms?
- Проверка работы приложения Windows
- Панель не получает фокус
- Доступ к управлению пользовательским интерфейсом из BackgroundWorker Thread
- Недопустимый URI: формат URI не может быть определен
- Событие, зарегистрированное в CheckedListBox?
- Как найти элемент управления, который я добавил в форму?
- Как создать событие в Usercontrol и обработать его в основной форме?
- Индекс выбранной строки в DataGridView
- Воспроизведение файла MP3 в приложении WinForm
- Как написать код WinForms, который автоматически масштабируется до системных настроек шрифта и dpi?
Вам нужно будет использовать 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)); } }