控件复制之后无法更改位置

龍五1618 2019-12-19 12:35:32
本人使用一段自己抄的控件复制代码更改出来的控件复制,但是复制出来的控件却无法更改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);
}


测试代码示例:
...全文
187 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
龍五1618 2019-12-24
  • 打赏
  • 举报
回复
引用 11 楼 github_36000833 的回复:
控件复制不是好主意,为何要跟它过不去呢?

如果你要复用控件,最直接的方法就是做一个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);
}
}
}

重做控件应该是个好主意,但是无奈是本人技术有限+懒,无法对其中每一个的控件的事件进行重新注册和调整。(主要是想写个一劳永逸的方法
github_36000833 2019-12-22
  • 打赏
  • 举报
回复
控件复制不是好主意,为何要跟它过不去呢? 如果你要复用控件,最直接的方法就是做一个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);
        }
    }
}
龍五1618 2019-12-22
  • 打赏
  • 举报
回复
引用 5 楼 Summer_djz 的回复:
控件Refresh

父控件Refresh,不行
新生成的控件Refresh,不行
整个界面Refresh,不行
我都已经快郁闷了,搞不清到底因为什么原因导致的。
龍五1618 2019-12-22
  • 打赏
  • 举报
回复
引用 7 楼 大然然 的回复:
你先说说场景,为什么你想复制控件,我们可以帮你看看有没有另外的方式解决

场景就是我需要多少组控件不确定,根据用户自己调,然后界面自动变化。
龍五1618 2019-12-22
  • 打赏
  • 举报
回复
引用 6 楼 北京的雾霾天 的回复:
检查下生成 groupbox 的父控件,是不是所在的容器不是预期那个导致的。

父控件没错,从父控件中也能获取到新复制出来的控件,但是就是位置不能更改,名字却可以更改
牧歌ing 2019-12-20
  • 打赏
  • 举报
回复
控件Refresh
大然然 2019-12-20
  • 打赏
  • 举报
回复
你先说说场景,为什么你想复制控件,我们可以帮你看看有没有另外的方式解决
北京的雾霾天 2019-12-20
  • 打赏
  • 举报
回复
检查下生成 groupbox 的父控件,是不是所在的容器不是预期那个导致的。
龍五1618 2019-12-19
  • 打赏
  • 举报
回复
引用 3 楼 北京的雾霾天 的回复:
界面上会不会显示有一个小锁的标记,如果有就是给锁定了,在格式菜单中找到去掉锁就行。
不是锁的就得要道再找具体原因了。

一。原先的GroupBox并没有进行锁定控件的操作。
二。由于我是新生成的一个GroupBox,跟原先的GroupBox是两个对象。我是指新生成的这个GroupBox不能设置Location,原先的GroupBox能够重新设置Location,并无影响。
至于为什么新生成的这个GroupBox不能设置Location,一直想不明白。
北京的雾霾天 2019-12-19
  • 打赏
  • 举报
回复
界面上会不会显示有一个小锁的标记,如果有就是给锁定了,在格式菜单中找到去掉锁就行。 不是锁的就得要道再找具体原因了。
龍五1618 2019-12-19
  • 打赏
  • 举报
回复
引用 1 楼 github_36000833 的回复:
不要复制Winform控件。
因为Winform控件底层上,是由Windows系统的内核对象支持的,单单复制Control的私有成员不是常规和安全的做法。

那请问winform批量添加控件该如何添加?
github_36000833 2019-12-19
  • 打赏
  • 举报
回复
不要复制Winform控件。 因为Winform控件底层上,是由Windows系统的内核对象支持的,单单复制Control的私有成员不是常规和安全的做法。

17,748

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧