在標題中很難解釋這一點,如果有人想改變它就沒關係。WPF:在沒有「程序員」干預的情況下關閉應用程序關閉時的輔助窗口
我有一種情況,在WPF中,我爲程序員創建了一個「隱藏」窗口,它是透明的。 我的意思是這個窗口是在靜態構造函數中創建的,隱藏並移動到屏幕之外,它的寬度和高度都是0.這是因爲我使用這個窗口來執行一些互操作,並允許一些處理程序所有的WndProcs都會覆蓋某人可能需要的地方(有一個委託列表處理應該覆蓋WndProc的方法)。我的問題是,當我創建一個WPF項目並啓動它時,如果我關閉主窗口(這不是創建的透明地創建的窗口)給程序員),我想讓我的應用程序關閉。但是,我創建的代碼除了使用Application.Current.Shutdown();
有沒有辦法解決這個問題,而不調用該方法?我想要一種透明的方式,其他程序員甚至不應該注意到(這是一個lib,不應該以這種方式改變工作程序的行爲)。
感謝您的任何建議,在這裏你可以看到一些代碼片段:
由LIB創建的窗口
public class InteropWindow : Window
{
public HwndSource Source { get; protected set; }
private static InteropWindow _Instance;
static InteropWindow()
{
_WndProcs = new LinkedList<WndProcHandler>();
_Instance = new InteropWindow();
}
private static WindowInteropHelper _InteropHelper;
public static WindowInteropHelper InteropHelper
{
get
{
if (_InteropHelper == null)
{
_InteropHelper = new WindowInteropHelper(_Instance);
_InteropHelper.EnsureHandle();
}
return _InteropHelper;
}
}
public static IntPtr Handle { get { return InteropHelper.Handle; } }
private InteropWindow()
{
Opacity = 0.0;
//We have to "show" the window in order to obtain hwnd to process WndProc messages in WPF
Top = -10;
Left = -10;
Width = 0;
Height = 0;
WindowStyle = WindowStyle.None;
ShowInTaskbar = false;
ShowActivated = false;
Show();
Hide();
}
private static LinkedList<WndProcHandler> _WndProcs;
public static void AddWndProcHandler(WndProcHandler handler)
{
_WndProcs.AddLast(handler);
}
public static void RemoveWndProcHandler(WndProcHandler handler)
{
_WndProcs.Remove(handler);
}
private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
IntPtr result = IntPtr.Zero;
foreach (WndProcHandler handler in _WndProcs)
{
IntPtr tmp = handler(hwnd, msg, wParam, lParam, ref handled);
if (tmp != IntPtr.Zero)
{
if (result != IntPtr.Zero)
throw new InvalidOperationException(string.Format("result should be zero if tmp is non-zero:\nresult: {0}\ntmp: {1}", result.ToInt64().ToString(), tmp.ToInt64().ToString()));
result = tmp;
}
}
return result;
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
Source = PresentationSource.FromVisual(this) as HwndSource;
Source.AddHook(WndProc);
OnWindowInitialized(null, e);
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
if (Source != null)
Source.RemoveHook(WndProc);
OnWindowClosed(null, e);
}
private static void OnWindowInitialized(object sender, EventArgs e)
{
if (WindowInitialized != null) WindowInitialized(sender, e);
}
private static void OnWindowClosed(object sender, EventArgs e)
{
if (WindowClosed != null) WindowClosed(sender, e);
}
public static event EventHandler WindowInitialized;
public static event EventHandler WindowClosed;
}
使用WPF(從項目創建的基本窗口)創建一個正常的窗口
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ExClipboard.ClipboardUpdate += new RoutedEventHandler(ExClipboard_ClipboardUpdate);
Closed += new EventHandler(MainWindow_Closed);
}
private void MainWindow_Closed(object sender, EventArgs e)
{
//InteropWindow.Dispose();
App.Current.Shutdown(0);
}
}
更新1:
爲了回答你的答案,我不希望避免程序員使用我的庫進行任何干預,所以理想的解決方案是,在我的庫中我訂閱了一些Application.Exit事件並關閉了我的窗口,顯然我可以不使用Application.Exit是因爲應用程序沒有關閉,因爲我的窗口沒有關閉
也許有一種方法可以計算屬於應用程序的所有窗口嗎?我也可以這樣做
良好的工作伴侶,你的黑客工作很大,正是我一直在尋找:) –
在應用程序中設置ShutDownMode。 xaml到OnMainWindow關。 –
@JesseSeger這個想法(在這種情況下)是讓它在lib中處理,而不是依賴最終的開發人員干預。爲這個問題提供的其他答案將是通常做到這一點的最佳方式,但不適用於此特定情況。 – fatty