2009-11-04 151 views
3

在我编写的程序中,用户可以将控件添加到窗体并将它们移动并在伪设计模式下设置一些属性。我希望能够在按下按钮切换到“数据模式”时将所有这些控件锁定到一个位置。我怎样才能做到这一点?我希望能够遍历所有控件并使用锁定属性,但我注意到它并未在智能感知中显示。C#锁定WinForm控件

谢谢!

回答

2

我对“伪设计模式”假设你的意思是,你的应用程序在运行时的状态,以及最终用户正在经历一个“虚拟设计模式”:如果我请大家指正我错了。

但是,我假设你指的是设计时的“控件锁定属性,您希望‘效仿’这在运行时......是否正确?

我还假设你将鼠标上/下/移动处理程序连接到允许移动的控件上,可能是通过循环遍历表单上的控件或其子集保持允许移动的控制)。

如果我的假设是正确的,我会去删除事件处理程序,使当你需要禁用控制移动,然后恢复这些事件处理程序,当你需要允许控制要再次移动移动。

其中一个主要原因是,严格控制事件处理的“最佳实践”(离开事件处理程序“原地”可能会干扰对象处理......尽管这可能不适用于到你这里的场景)。

还有一个想法:你有一个“不可见的”面板停靠“填充到窗体中:在这个面板上是所有可以移动的控件:这可以让你更轻松地”缩小你的焦点“花费“这个额外的代码。在使用这种方法的缺点通常是:

  1. 如果使用hostingForm.ActiveControl确定哪些控制得到了鼠标按下(因此,然后可以移动):你会发现一些控件,如标签,和pictureboxes,当点击时不会成为窗体的主动控件,但大多数都是。

  2. 你有一个“z-顺序”的事情要考虑,因为一个控制不在你的面板封装你希望允许移动发送到伪透明面板后面的控件将被隐藏。

出于这些原因,恕我直言,我认为禁用和重新启用的事件处理程序的附件是最好,最简单,因为它可以当控件是“向下转换”到其控制的“身份”来完成:

private void enableControlsMove() 
{ 
    foreach (Control theControl in panel1.Controls) 
    { 
     Console.WriteLine(theControl.Name); 

     theControl.MouseDown += new MouseEventHandler(theControl_MouseDown); 
     theControl.MouseUp += new MouseEventHandler(theControl_MouseUp); 
     theControl.MouseMove += new MouseEventHandler(theControl_MouseMove); 
    } 
} 

private void disableControlsMove() 
{ 
    foreach (Control theControl in panel1.Controls) 
    { 
     Console.WriteLine(theControl.Name); 

     theControl.MouseDown -= theControl_MouseDown; 
     theControl.MouseUp -= theControl_MouseUp; 
     theControl.MouseMove -= theControl_MouseMove; 
    } 
} 

我以这种方式使用它。

最好,比尔

+0

这是我昨晚在阅读本文之前最终做的。这很简单,快捷。 – Nathan 2009-11-04 19:25:20

3

Locked属性不是一个真实的属性 - 它是Windows窗体设计器添加的属性(如生成成员和修饰符“属性”)。因此,您需要自己模拟它,无论是在表单级别还是在控制级别(如果需要)(例如用字典中的哪些控件都被锁定),并在您为移动控件编写的代码中手动检查。

2

锁定控件可以防止它们在设计图面上被拖动到新的尺寸或 位置。 但是,您仍然可以通过属性窗口或代码更改 的大小或通过 控件的位置。

MSDN

我想这是一个明显的对设计师唯一的财产。我认为你必须实现你自己的冻结机制 - 一个小标志在设计模式和使用模式之间切换。

更新:似乎自定义设计器类可以添加控件的属性,根据它们是否处于设计模式。
如果您打算采取VS建筑锤道,更多详细信息请点击此处。无论如何,价值10分钟的阅读时间。
Custom Design-time Control Features in Visual Studio .NET - Dino Esposito