2009-11-04 463 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