【问题标题】:Container UserControl - Handle and Modify Added ControlsContainer UserControl - 处理和修改添加的控件
【发布时间】:2016-04-07 16:23:40
【问题描述】:

我正在尝试将自定义容器创建为UserControl

我的目标:我希望能够在设计器中拖动控件并在我的用户控件的代码中处理传入的控件。

示例:我将容器放在某处,然后添加一个按钮。在这个moemt中,我希望我的用户控件自动调整此按钮的宽度和位置。这就是我卡住的地方。

我的代码:

[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class ContactList : UserControl
{
    public ContactList()
    {
        InitializeComponent();
    }        

    private void ContactList_ControlAdded(object sender, ControlEventArgs e)
    {
        e.Control.Width = 200;   // Nothing happens
        e.Control.Height = 100;  // Nothing happens

        MessageBox.Show("Test"); // Firing when adding a control
    }
}

MessageBox 运行良好。 widthheight 集合被忽略。
问题只是“为什么?”。


编辑

我刚刚注意到,在放置按钮并使用 F6 重新编译时,按钮的大小会调整为 200x100。为什么放置时这不起作用?

我的意思是...FlowLayoutPanel 在您放置时处理添加的控件。这就是我正在寻找的确切行为。

【问题讨论】:

标签: c# winforms user-controls windows-forms-designer designer


【解决方案1】:

使用 OnControlAdded

要修复您的代码,当您在容器上放置一个控件并希望在OnControlAdded 中设置一些属性时,您应该使用BeginInvoke 设置属性,这样控件的大小会改变,但大小句柄不会改变更新。然后要更新设计器,您应该通知设计器更改控件的大小,使用IComponentChangeService.OnComponentChanged

以下代码仅在您将控件添加到容器时才会执行。之后,它会根据您使用尺寸抓取手柄为控件设置的尺寸。适合在设计时进行初始化。

protected override void OnControlAdded(ControlEventArgs e)
{
    base.OnControlAdded(e);
    if (this.IsHandleCreated)
    {
        base.BeginInvoke(new Action(() =>
        {
            e.Control.Size = new Size(100, 100);
            var svc = this.GetService(typeof(IComponentChangeService)) 
                          as IComponentChangeService;
            if (svc != null)
                svc.OnComponentChanged(e.Control, 
                   TypeDescriptor.GetProperties(e.Control)["Size"], null, null);
        }));
    }
}

【讨论】:

  • 我从 @HansPassant 在第一条评论中发布的 msdn 中获取了示例。这个anwser接近它。 msdn.microsoft.com/en-us/library/…
  • 如果你不使用BeginInvoke,它不适用于WidthHeight,但是对于像Dock这样的属性,它可以在没有BeginInvoke的情况下工作,这可能是因为当我们在没有BeginInvoke的情况下设置大小是在设计者设置控件提供的默认大小之前,然后它将替换我们提供的值,但是使用BeginInvoke它在完成向父级添加控件的任务后使用我们提供的值。
  • 感谢您的关注。我会在几分钟内检查并回复。
  • OnComponentChanged 不会触发我。 OnComponentAdded 运行良好。不幸的是,我需要两者的结合。你知道为什么Changed 事件没有触发吗?我在设计器中调整了一些控件的大小,但什么也没发生...
  • 我将删除解决方案 2,因为我认为它需要一些改进。希望您发现答案有用:)
猜你喜欢
  • 2012-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
相关资源
最近更新 更多