2011-10-12 41 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。 –