在.NET中是否有相当于Mac OS X Document的模式表?

时间:2011-10-12 13:43:37

标签: c# .net-4.0 modal-dialog

我的应用程序越来越多地要求某些对话框的行为类似于Mac OS X Document modal Sheet功能,其中对话框只是父控件/对话框的模态,而不是整个应用程序(参见http://en.wikipedia.org/wiki/Window_dialog })。

当前窗口ShowDialog()不足以满足我的应用程序的需要,因为我需要在应用程序中将对话框设置为另一个对话框,但仍然允许用户访问应用程序的其他区域。

C#.NET中是否有与Document模式表相同的内容?或者甚至是某个人做过的近距离实施,还是我自己尝试实现这个功能?我试着搜索Google和SO无济于事。

谢谢,

凯尔

2 个答案:

答案 0 :(得分:2)

在重新审视这个问题之后,我做了一些挖掘,找到了一个适合我需求的混合解决方案。

我接受了p-daddyhttps://stackoverflow.com/a/428782/654244

的建议

我使用hans-passant的建议修改了代码以适用于32位和64位编译: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 :(得分:1)

Form.ShowDialog方法允许您在调用时指定所有者。在这种情况下,表单仅对给定的所有者是模态的。

编辑:我尝试了这个混合结果。我创建了一个带有主窗体的简单Windows窗体应用程序和另外两个。从按钮单击主窗体,我使用Show方法打开Form2。 Form2上也有一个按钮,点击后,我使用ShowDialog方法打开Form3,传入Form2作为它的所有者。虽然Form3看起来似乎是Form2的模态,但在关闭Form3之前,我无法切换回Form1。