Есть ли в .NET эквивалент модального листа Mac OS X Document? - PullRequest
2 голосов
/ 12 октября 2011

Мое приложение получало все больше запросов, чтобы определенные диалоги вели себя как Mac OS X Document modeal Sheet , где диалог является модальным только для родительского элемента управления / диалога, а не для всего диалогаприложение (см. http://en.wikipedia.org/wiki/Window_dialog).

Текущие окна ShowDialog () недостаточны для нужд моего приложения, так как мне нужно, чтобы диалог был модальным для другого диалога в приложении, но все же позволял пользователючтобы получить доступ к другим областям приложения.

Существует ли эквивалент модального листа документа в C # .NET? Или даже близкая реализация, которую кто-то сделал, или я сам пытаюсь реализовать эту функцию?попробовал поискать в Google и SO безрезультатно.

Спасибо,

Кайл

Ответы [ 2 ]

2 голосов
/ 18 апреля 2013

После повторного рассмотрения этой проблемы я немного покопался и нашел гибридное решение, которое будет работать для моих нужд.

Я принял предложение p-daddy : https://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 голос
/ 12 октября 2011

Метод Form.ShowDialog позволяет указать владельца при его вызове.В этом случае форма является модальной только для данного владельца.

РЕДАКТИРОВАТЬ: я пробовал это со смешанными результатами.Я создал простое приложение Windows Forms с основной формой и двумя другими.Нажав кнопку на главной форме, я открыл форму Form2 с помощью метода Show.На Form2 также есть кнопка, и когда я щелкнул, я открыл Form3 с помощью метода ShowDialog, передав Form2 в качестве владельца.Хотя Form3 действительно показалась модальной для Form2, я не мог переключиться обратно в Form1, пока не закрыл Form3.

...