2008-11-13 39 views
2

Vista已經引入了一個新的API,用於在列表視圖控件中沒有任何項目時顯示文本。正如MSDN庫所述,我應該處理LVN_GETEMPTYMARKUP通知。ListView空標記文本

在繼承ListView控制WndProc方法重寫:

protected override void WndProc(ref Message m) { 
    try { 
    if(m.Msg == 78 /* WM_NOTIFY */) { 
     var nmhdr = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR)); 
     if(nmhdr.code == -187 /* LVN_GETEMPTYMARKUP */) { 
     var nmlvemptymarkup = 
      (NMLVEMPTYMARKUP)Marshal.PtrToStructure(m.LParam, typeof(NMLVEMPTYMARKUP)); 
     nmlvemptymarkup.szMarkup = "The ListView is empty."; 
     m.Result = (IntPtr)1; 
     } 
    } 
    } finally { 
    base.WndProc(ref m); 
    } 
} 

但是,它不工作(雖然它不拋出任何異常)。其實我從來沒有得到nmhdr.code等於-187。有任何想法嗎?

+0

你能發佈一個鏈接到MSDN上的頁面嗎? – configurator 2008-11-13 15:52:05

+0

http://msdn.microsoft.com/en-us/magazine/cc163384.aspx – 2008-11-13 16:30:42

回答

0

我自己也爲此掙扎了很多。

要使原始問題中的代碼正常工作,請使用[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Unicode)](CharSet.Unicode非常重要)標記NMLVEMPTYMARKUP結構。

此外,設置標記值後,調用Marshal.StructureToPtr(nmlvemptymarkup,m.LParam,false)將數據複製回LParam指向的緩衝區。

0

另一種解決方案(這樣你就不必監視的WndProc),是添加油漆處理程序是這樣的:

listview_onPaint(object sender, eventargs e) 
{ 
    if (listview.items.count <= 0) 
    { 
    e.graphics.drawstring("The Listview is empty"); //put all the proper args in here! 
    } 
} 

從內存中,多數民衆贊成,但你應該明白我的意思。

希望這有些幫助。

2

WM_NOTIFY消息不會發送到控件(列表視圖),而是發送給父級(表單)。這在Win32世界中是有道理的,因爲這些消息對攔截非常有用,但是對控件進行子類化是非常痛苦的,尤其是當你想要在每種情況下使用不同的行爲時。 .NET不再是這種情況。

方便的是,標準的.NET消息處理「反射」了控件上的消息,這樣就可以截獲消息並在控件的WndProc中處理它 - 但反射的消息不再是WM_NOTIFY(0x004E),而是WM_REFLECT | WM_NOTIFY(0x204E)。

所以,如果你修改你的WndProc來尋找那個值,那麼它應該工作。