WPF全局开/关对话事件?

时间:2012-12-15 17:14:42

标签: wpf events dialog event-handling

在我的WPF应用程序中,我想订阅一些事件/ callbeck /无论何时在我的应用程序中打开(并关闭)对话框窗口时都会告诉我。

我找到了窗口集合,但这是一个简单的容器,它似乎没有提供任何订阅方式。

我也尝试过使用事件处理程序,但似乎没有一个事件告诉我我需要什么。

有什么想法吗?

4 个答案:

答案 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);
    }

上面的链接似乎在实例上注册了一个空处理程序,以使事情正常运行。