2016-08-11 4 views
0

У меня есть SaveFileDialog в моем проекте WPF.События кнопки SaveFileDialog в WPF

Если SaveFileDialog закрыт красным «x» в углу, я хочу, чтобы диалоговое окно закрылось и пользователь был возвращен в основное приложение.

Однако, если «SaveFileDialog« отменен », я хочу, чтобы все приложение было закрыто.

Единственная проблема, с которой я сталкиваюсь, - это знать, нажал ли пользователь красную кнопку x или кнопку отмены. Оба они оценивают значение false в коде ниже.

SaveFileDialog saveFileDialog = new SaveFileDialog(); 
saveFileDialog.Filter = "Text file (*.txt)|*.txt"; 
var dlg = saveFileDialog.ShowDialog(); 
if (dlg == true) 
{ 
    //When the user presses save 
    File.WriteAllLines(saveFileDialog.FileName, rowList); 
    ExitApp(); 
} 
else if (dlg == false) 
{ 
    //This occurs when red x or cancel is pressed. 
} 

Есть ли способ различать два в WPF?

ответ

0

Это не так просто, но вы можете сделать это с помощью hooks и метод SetWindowsHookEx.

Прежде всего нам нужен класс для регистрации и регистрации нашего крюка:

public class WinHooker 
{ 
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] 
    private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 
    private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] 
    private static extern int UnhookWindowsHookEx(int idHook); 

    private delegate int HookProc(int nCode, int wParam, IntPtr lParam); 

    private HookProc hookDelegate; 
    private int hookHandle; 
    private bool wasClosedButtonPressed; 

    private static WinHooker instance; 

    private WinHooker() 
    { 
    } 

    public static WinHooker Instance 
    { 
     get 
     { 
      if (instance == null) 
      { 
       instance = new WinHooker(); 
      } 

      return instance; 
     } 
    } 

    public bool WasClosedButtonPressed 
    { 
     get 
     { 
      return wasClosedButtonPressed; 
     } 
    } 

    public void Register() 
    { 
     wasClosedButtonPressed = false; 
     hookDelegate = this.HookProcHandler; 

     hookHandle = SetWindowsHookEx(5, 
      hookDelegate, 
      IntPtr.Zero, 
      AppDomain.GetCurrentThreadId()); 
    } 

    public void Unregister() 
    { 
     UnhookWindowsHookEx(hookHandle); 
     hookHandle = 0; 
     hookDelegate = null; 
    } 

    private int HookProcHandler(int nCode, int wParam, IntPtr lParam) 
    { 
     if (nCode >= 0) 
     { 
      if (nCode == 8 && wParam == 0xF060) 
      { 
       wasClosedButtonPressed = true; 
      } 
     } 

     return CallNextHookEx(hookHandle, nCode, wParam, lParam); 
    } 
} 

Как вы можете видеть, что я использовал 5 в качестве первого параметра для SetWindowsHookEx, так как он соответствует к WH_CBT значения (см. SetWindowsHookEx page). Кроме того, значения в методе HookProcHandler (то есть nCode == 8 && wParam == 0xF060) могут быть получены из here.

Теперь давайте использовать наш класс в коде:

SaveFileDialog saveFileDialog = new SaveFileDialog(); 

WinHooker.Instance.Register(); 
saveFileDialog.ShowDialog(); 
WinHooker.Instance.Unregister(); 

if (WinHooker.Instance.WasClosedButtonPressed) 
{ 
    MessageBox.Show("Oh my God! What have you done??"); 
} 

Как вы можете понять, WasClosedButtonPressed устанавливается истина только если пользователь закрывает диалоговое окно, нажав на красный «х» в углу. В противном случае это неверно.

Надеюсь, это может вам помочь.

+0

Благодарим вас за то, что нашли время, чтобы обеспечить это. Надеюсь, это поможет кому-то другому, поскольку я решил не беспокоиться. – Mercender

Смежные вопросы