本人使用一段自己抄的控制元件復制代碼更改出來的控制元件復制,但是復制出來的控制元件卻無法更改Location位置,請各位大神指導一下到底是哪個地方可能出現的問題。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsFormsApp2.Command
{
internal static class StaticHelper
{
internal static T LastByName<T>(this System.Windows.Forms.Control.ControlCollection cll, Func<T, bool> func) where T : System.Windows.Forms.Control
{
if (cll is null)
{
throw new ArgumentNullException(nameof(cll));
}
if (func is null)
{
throw new ArgumentNullException(nameof(func));
}
IList<T> list = new List<T>();
foreach (T item in cll)
{
list.Add(item);
}
list.OrderBy(col => col.Name);
return list.Last(func);
}
internal static T Clone<T>(this T col, Func<System.Windows.Forms.Control, string> funcName) where T : System.Windows.Forms.Control
{
col.SuspendLayout();
if (col == null)
{
return null;
}
Type colType =typeof(T);
System.Windows.Forms.Control restultCol = Activator.CreateInstance(colType) as System.Windows.Forms.Control;
System.Reflection.PropertyInfo[] proInfo = colType.GetProperties();
System.Reflection.FieldInfo[] fieInfo = colType.GetFields();
foreach (System.Reflection.FieldInfo item in fieInfo)
{
object newValue = item.GetValue(col);
if (newValue == null)
{
continue;
}
item.SetValue(restultCol, newValue);
}
foreach (System.Reflection.PropertyInfo item in proInfo)
{
object newValue = item.GetValue(col);
if (newValue == null)
{
continue;
}
if (item.Name == "Name")
{
newValue = funcName(col);
}
if (item.CanWrite)
{
item.SetValue(restultCol, newValue);
}
}
if (col.Controls.Count > 0)
{
foreach (System.Windows.Forms.Control item in col.Controls)
{
restultCol.Controls.Add(item.Clone(funcName));
}
}
col.ResumeLayout();
return restultCol as T;
}
}
}
/// <summary>
/// 復制一個一模一樣的控制元件
/// </summary>
/// <param name="col"></param>
/// <returns></returns>
private void AddGroupBox()
{
this.groupBoxResult.Hide();
var regex = new System.Text.RegularExpressions.Regex(@"(\D+)(\d+)");
List<Tuple<Type, int>> tuples = this.GetTuples(this.groupBoxBroder);
GroupBox group = this.groupBox1.Clone(t =>
{
if (regex.IsMatch(t.Name))
{
string firstName = regex.Matches(t.Name)[0].Groups[1].Value;
string endIndex = regex.Matches(t.Name)[0].Groups[2].Value;
int tempNum = int.Parse(endIndex);
Tuple<Type, int> tuple = tuples.FirstOrDefault(s => s.Item1 == t.GetType());
if (tuple != null)
{
while (tempNum <= tuple.Item2)
{
tempNum++;
}
}
else
{
}
tuples.Remove(tuple);
tuples.Add(new Tuple<Type, int>(t.GetType(), tempNum));
return firstName + tempNum;
}
else
{
return t.Name;
}
});
System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"^groupBox\d+$");
group.Location = new Point(173, 40);
GroupBox group1 = this.groupBoxBroder.Controls.LastByName<GroupBox>(t => reg.IsMatch(t.Name));
group1.Location = new Point(173, 80);
}
測驗代碼示例:
uj5u.com熱心網友回復:
不要復制Winform控制元件。因為Winform控制元件底層上,是由Windows系統的內核物件支持的,單單復制Control的私有成員不是常規和安全的做法。
uj5u.com熱心網友回復:
那請問winform批量添加控制元件該如何添加?
uj5u.com熱心網友回復:
界面上會不會顯示有一個小鎖的標記,如果有就是給鎖定了,在格式選單中找到去掉鎖就行。不是鎖的就得要道再找具體原因了。
uj5u.com熱心網友回復:
一。原先的GroupBox并沒有進行鎖定控制元件的操作。
二。由于我是新生成的一個GroupBox,跟原先的GroupBox是兩個物件。我是指新生成的這個GroupBox不能設定Location,原先的GroupBox能夠重新設定Location,并無影響。
至于為什么新生成的這個GroupBox不能設定Location,一直想不明白。
uj5u.com熱心網友回復:
控制元件Refreshuj5u.com熱心網友回復:
檢查下生成 groupbox 的父控制元件,是不是所在的容器不是預期那個導致的。uj5u.com熱心網友回復:
你先說說場景,為什么你想復制控制元件,我們可以幫你看看有沒有另外的方式解決uj5u.com熱心網友回復:
父控制元件沒錯,從父控制元件中也能獲取到新復制出來的控制元件,但是就是位置不能更改,名字卻可以更改
uj5u.com熱心網友回復:
場景就是我需要多少組控制元件不確定,根據用戶自己調,然后界面自動變化。
uj5u.com熱心網友回復:
父控制元件Refresh,不行
新生成的控制元件Refresh,不行
整個界面Refresh,不行

我都已經快郁悶了,搞不清到底因為什么原因導致的。
uj5u.com熱心網友回復:
控制元件復制不是好主意,為何要跟它過不去呢?如果你要復用控制元件,最直接的方法就是做一個UserControl。一個用戶控制元件可以提供豐富的UI,也容易做為一個整體來使用。
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Text = "點擊滑鼠,增加選項";
this.MouseClick += 添加選項;
}
private void 添加選項(object sender, MouseEventArgs e)
{
var g = new MyGroupControl();
g.Location = new Point(10, 選項數目 * (g.Height + 10));
this.Controls.Add(g);
選項數目++;
}
int 選項數目;
}
// 用戶控制元件一般用可視編輯,這里直接用代碼簡化例子。
public class MyGroupControl : UserControl
{
GroupBox _groupBox = new GroupBox() { Dock = DockStyle.Fill, Text = "配置選項" };
FlowLayoutPanel _flowPanel = new FlowLayoutPanel() { Dock = DockStyle.Fill };
CheckBox _checkBox1 = new CheckBox() { Text = "彩色" };
CheckBox _checkBox2 = new CheckBox() { Text = "橫向" };
CheckBox _checkBox3 = new CheckBox() { Text = "高清" };
public MyGroupControl()
{
_flowPanel.Controls.AddRange(new[] { _checkBox1, _checkBox2, _checkBox3 });
_groupBox.Controls.Add(_flowPanel);
this.Controls.Add(_groupBox);
this.Size = new Size(180, 120);
}
}
}
uj5u.com熱心網友回復:
重做控制元件應該是個好主意,但是無奈是本人技術有限+懶,無法對其中每一個的控制元件的事件進行重新注冊和調整。(主要是想寫個一勞永逸的方法
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/82403.html
