在上一次的嘗試中,我們已經可以進行控制項的添加了。但後來我發現了一個bug, 就是畫好一個控制項後,居然還可以接著畫出這個控制項,這不符合我們的習慣。一般情況下我們希望畫好控制項後,滑鼠變回選擇狀態。這個功能在.net 2.0以前的做法是實現IToolboxService的void SelectedToolboxItemUsed()方法,但是在.net 2.0中我們已經可以用更簡單的辦法,前面討論過,在.net 2.0中我們是通過繼承ToolboxService類而不是完全實現IToolboxService的方式來簡化工具箱功能。分析ToolboxService的原始碼,可以看到它已經實現了SelectedToolboxItemUsed()方法, 其代碼如下:
void IToolboxService.SelectedToolboxItemUsed()
{
this.SelectedItemContainerUsed();
}
protected virtual void SelectedItemContainerUsed()
{
this.SelectedItemContainer = null;
}
很顯然,它預設的方式將SelectedItemContainer屬性值賦值為null, 這時候我們可以想到一個簡便的辦法是並不需要重載SelectedItemContainerUsed(), 而是修改SelectedItemContainer屬性的set方法,找到上次嘗試的代碼,在SelectedItemContainer屬性的set方法上寫上:
if (value == null)
{
toolBox.SelectedIndex = -1;
}
不過後來我覺得還是象vs的工具箱一樣,提供一個”Point”的“虛”工具更方便。這個功能只要在我們前面的代碼上對幾個小地方稍作修改就可以了,就不帖代碼了。
接下來的步驟是實現能在PropertyGrid中隨意修改任何控制項的屬性。要做到這點也很簡便,只要為DesignSurface的SelectionService實現一個SelectionChanged事件就行了。
切換到Form1的代碼視窗,為表單類添加一個私人成員:
private ISelectionService selectionService;
然後在Load事件的最後加上:
selectionService = surface.GetService(typeof(ISelectionService)) as ISelectionService;
selectionService.SelectionChanged += new EventHandler(selectionService_SelectionChanged);
當然也為表單類加上以下事件方法:
void selectionService_SelectionChanged(object sender, EventArgs e)
{
object[] selection;
if (selectionService.SelectionCount == 0)
propertyGrid1.SelectedObject = null;
else
{
selection = new object[selectionService.SelectionCount];
selectionService.GetSelectedComponents().CopyTo(selection, 0);
propertyGrid1.SelectedObjects = selection;
}
}
以下是運行時介面:
好象是大功告成了,不過控制項只能添加,卻怎麼刪除不了。
當然,還有一些必不可少的功能,如將設計內容序列化到資源檔或者產生代碼檔案等等。胡適先生說:“自古成功嘗試始”,我想一定會在以後幾節的嘗試中成功實現這些功能的。
相關章節:
寫Form設計器嘗試(一)
寫Form設計器嘗試(二) PropertyGrid
寫Form設計器嘗試(三) 在表單上添加控制項