2011-10-12 44 views
2

我的應用程序越來越多的請求讓某些對話框的行爲類似於Mac OS X Document modal Sheet功能,其中對話框僅對父控制/對話框模式化,而不是整個應用程序(請參閱http://en.wikipedia.org/wiki/Window_dialog)。在.NET中是否有相當於Mac OS X Document模式表單?

當前窗口ShowDialog()不足以滿足我的應用程序的需要,因爲我需要將對話框模態化爲應用程序中的另一個對話框,但仍允許用戶訪問應用程序的其他區域。

在C#.NET中是否存在與文檔模式表的等價物?或者甚至是某個人已經完成的緊密實現,或者我自己嘗試並實現此功能?我試圖搜索Google和SO無濟於事。

感謝,

凱爾

回答

2

在重新審視這個問題之後,我做了一些挖掘並找到了一個適合我需求的混合解決方案。

我把建議通過p-daddyhttps://stackoverflow.com/a/428782/654244

我修改的代碼爲32位和64位編譯使用建議通過hans-passant工作:https://stackoverflow.com/a/3344276/654244

結果如下:

const int GWL_STYLE = -16; 
const int WS_DISABLED = 0x08000000; 

public static int GetWindowLong(IntPtr hWnd, int nIndex) 
{ 
    if (IntPtr.Size == 4) 
    { 
     return GetWindowLong32(hWnd, nIndex); 
    } 
    return GetWindowLongPtr64(hWnd, nIndex); 
} 

public static int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong) 
{ 
    if (IntPtr.Size == 4) 
    { 
     return SetWindowLong32(hWnd, nIndex, dwNewLong); 
    } 
    return SetWindowLongPtr64(hWnd, nIndex, dwNewLong); 
} 

[DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)] 
private static extern int GetWindowLong32(IntPtr hWnd, int nIndex); 

[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Auto)] 
private static extern int GetWindowLongPtr64(IntPtr hWnd, int nIndex); 

[DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)] 
private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong); 

[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)] 
private static extern int SetWindowLongPtr64(IntPtr hWnd, int nIndex, int dwNewLong); 


public static void SetNativeEnabled(IWin32Window control, bool enabled) 
{ 
    if (control == null || control.Handle == IntPtr.Zero) return; 

     NativeMethods.SetWindowLong(control.Handle, NativeMethods.GWL_STYLE, NativeMethods.GetWindowLong(control.Handle, NativeMethods.GWL_STYLE) & 
      ~NativeMethods.WS_DISABLED | (enabled ? 0 : NativeMethods.WS_DISABLED)); 
} 

public static void ShowChildModalToParent(IWin32Window parent, Form child) 
{ 
    if (parent == null || child == null) return; 

    //Disable the parent. 
    SetNativeEnabled(parent, false); 

    child.Closed += (s, e) => 
    { 
     //Enable the parent. 
     SetNativeEnabled(parent, true); 
    }; 

    child.Show(parent); 
} 
1

Form.ShowDialog方法可以讓你當你調用它指定一個所有者。在這種情況下,表單只對給定的所有者有模式。

編輯:我試過這個混合的結果。我用一個主表單創建了一個簡單的Windows窗體應用程序,還有兩個應用程序。從主窗體上點擊一個按鈕,我使用Show方法打開Form2。 Form2上也有一個按鈕,點擊後,我使用ShowDialog方法打開Form3,傳遞Form2作爲其所有者。雖然Form3似乎是Form2的模態,但我無法切換回Form1,直到我關閉Form3。

+0

它仍然阻止應用程序,但不是它。海報正在尋求一種方法,讓它阻止應用程序的一個窗口,同時允許來自同一應用程序的其他窗口繼續正常處理。 – tcarvin

+0

tcarvin是正確的。我會更詳細地更新我的問題。 – KyleK

+0

嘗試從主窗體打開第二個窗體(Form2a),使用「Show」,然後像以前一樣繼續。看看你是否可以切換到Form2a。 –