在我的WPF应用程序中,我想订阅一些事件/ callbeck /无论何时在我的应用程序中打开(并关闭)对话框窗口时都会告诉我。
我找到了窗口集合,但这是一个简单的容器,它似乎没有提供任何订阅方式。
我也尝试过使用事件处理程序,但似乎没有一个事件告诉我我需要什么。
有什么想法吗?
答案 0 :(得分:1)
如果没有为所有窗口创建一个Base类,你可以挂钩到打开的事件(或者手动将打开的事件添加到每个窗口),我不知道你是怎么知道什么时候创建新窗口的
可能有更优雅的方式,但您可以轮询Application.Current.Windows
以查看是否创建了任何新窗口,同时跟踪您找到的那个窗口。
这是一个粗略的例子,将演示如何使用DispatchTimer
轮询新窗口,跟踪找到的窗口并挂钩到已关闭的事件。
代码背后
public partial class MainWindow : Window
{
private DispatcherTimer Timer { get; set; }
public ObservableCollection<Window> Windows { get; private set; }
public MainWindow()
{
InitializeComponent();
// add current Window so we don't add a hook into it
Windows = new ObservableCollection<Window> { this };
Timer = new DispatcherTimer( DispatcherPriority.Background );
Timer.Interval = TimeSpan.FromMilliseconds( 500 );
Timer.Tick += ( _, __ ) => FindNewWindows();
Timer.Start();
this.WindowListBox.ItemsSource = Windows;
this.WindowListBox.DisplayMemberPath = "Title";
}
private void FindNewWindows()
{
foreach( Window window in Application.Current.Windows )
{
if( !Windows.Contains( window ) )
{
window.Closed += OnWatchedWindowClosed;
// inserting at 0 so you can see it in the ListBox
Windows.Insert( 0, window );
Feedback.Text = string.Format( "New Window Found: {0}\r\n{1}",
window.Title, Feedback.Text );
}
}
}
private void OnWatchedWindowClosed( object sender, EventArgs e )
{
var window = (Window)sender;
Windows.Remove( window );
Feedback.Text = string.Format( "Window Closed: {0}\r\n{1}",
window.Title, Feedback.Text );
}
private void CreateWindowButtonClick( object sender, RoutedEventArgs e )
{
string title = string.Format( "New Window {0}", DateTime.Now );
var win = new Window
{
Title = title,
Width = 250,
Height = 250,
Content = title,
};
win.Show();
e.Handled = true;
}
}
<强> XAML 强>
<Grid>
<ListBox Name="WindowListBox"
Width="251"
Height="130"
Margin="12,12,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
<TextBox Name="Feedback"
Width="479"
Height="134"
Margin="12,148,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
VerticalScrollBarVisibility="Auto" />
<Button Name="CreateWindowButton"
Width="222"
Height="130"
Margin="269,12,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="CreateWindowButtonClick"
Content="Create New Window"
FontSize="20" />
</Grid>
点击即可创建任意数量的新窗口;然后关闭它们。你会看到反馈发生的时候。当然,每当创建一个新窗口时,将会有500ms的延迟,因为DispatchTimer
的间隔设置为500ms。
答案 1 :(得分:1)
没有基类的一种方法是向MainWindow停用
添加处理程序如果打开一个新窗口,主窗口将失去焦点=您的&#34;新窗口事件&#34;
private readonly List<Window> openWindows = new List<Window>();
public void ApplicationMainWindow_Deactivated(object sender, EventArgs e)
{
foreach (Window window in Application.Current.Windows)
{
if (!openWindows.Contains(window) && window != sender)
{
// Your window code here
window.Closing += PopupWindow_Closing;
openWindows.Add(window);
}
}
}
private void PopupWindow_Closing(object sender, CancelEventArgs e)
{
var window = (Window)sender;
window.Closing -= PopupWindow_Closing;
openWindows.Remove(window);
}
答案 2 :(得分:0)
我从未听说过任何全球开放/关闭事件。
它应该以某种方式可行,但这可以让您控制所有窗口的打开和关闭。就像你构建了一个“基本窗口”(它自然地继承了“窗口”),你的所有对话框都是从窗口继承的。
然后你可以在“基本窗口”上有一个静态事件,你从基本窗口的开启和关闭(关闭(或卸载)事件)中发出一个静态事件,将“this”作为“发送者”发送。 您可以在App.xaml.cs类中访问该静态事件。
这是一个黑客,但它是可能的。
答案 3 :(得分:0)
您可以按照以下示例在App.cs中注册类处理程序
https://gist.github.com/mwisnicki/3104963
...
EventManager.RegisterClassHandler(typeof(UIElement), FrameworkElement.LoadedEvent, new RoutedEventHandler(OnLoaded), true);
EventManager.RegisterClassHandler(typeof(UIElement), FrameworkElement.UnloadedEvent, new RoutedEventHandler(OnUnloaded), true);
...
private static void OnLoaded(object sender, RoutedEventArgs e)
{
if (sender is Window)
Console.WriteLine("Loaded Window: {0}", sender);
}
private static void OnUnloaded(object sender, RoutedEventArgs e)
{
if (sender is Window)
Console.WriteLine("Unloaded Window: {0}", sender);
}
上面的链接似乎在实例上注册了一个空处理程序,以使事情正常运行。