wpf检测打开的窗口

时间:2009-12-05 02:06:24

标签: wpf events window

在我的WPF应用程序(csharp)中,我有一个事件处理程序,当触发时将打开应用程序的新窗口(窗口B)并显示一些数据。但是,当再次触发事件时,如果新窗口(窗口B)仍然打开,我不想生成窗口B的另一个实例,而只是更新当前实例中显示的数据。所以问题是:如何检测窗口B是否已经存在且仅在尚未打开时才打开,否则只需更新数据?

我找到了Application.Current.Window集合,但不知怎的,这对我来说还不起作用。想法?

5 个答案:

答案 0 :(得分:5)

您可以在WindowB中创建一个LoadWindow()方法,您可以调用该方法来加载(或刷新)数据&无论窗口是否已经打开,它都能正常工作。当这个窗口关闭时,是否需要代表打电话:

private Action ParentCallbackOnClose;

public void LoadWindow( Action parentCallbackOnClose ) {
    // load the data (set the DataContext or whatever)

    ParentCallbackOnClose = parentCallbackOnClose;    

    // Open the window and activate/bring to the foreground
    Show( );
    Activate( ); 
}

并让你的窗口关闭事件调用close委托:

private void WindowClosed( object sender, EventArgs e ) {
     ParentCallbackOnClose.Invoke( );
}

现在,从打开Window B的类开始,让它保持打开的那个实例,这样如果WindowB在有人试图重新加载时已经打开,它就会在现有实例上调用LoadWindow。有点像...

private WindowB WinB;

private void LoadWindowB(Content content)
{
    if (WinB == null ){
        WinB = new WindowB( );
    }
    WinB.LoadWindow(content, WindowBClosed);
}

然后你可以让它在关闭回调上使WinB无效,所以如果WinB关闭,那么下次调用LoadWindowB()时它将创建一个新的实例:

private void WindowBClosed( ){
    WinB = null;
}

答案 1 :(得分:0)

编辑: oops,我的答案特定于Windows窗体。我刚看到WPF提到了。我不确定WPF的具体代码是什么,但我想它在概念上并不是那么不同。我认为在WPF中,该属性称为IsVisible而不是Visible

您可以抓住窗口的实例(或将其设为Singleton)然后当您需要确定它是否可见时,请检查它的可见属性。

例如:

if(myWindow.Visible){
  myWindow.Hide();
}else{
  myWindow.Show();
}

答案 2 :(得分:0)

This article它是我在WPF页面之间传递数据的最佳选择。作者使用KISS方法提供了一个简单的解决方案。

答案 3 :(得分:0)

由于这是谷歌列出的第一个链接,几年前发布的,为了检查Window是否已经打开的解决方案,我会发布我的答案,其他人,我觉得更容易实现。 ChildWindow仅从MainWindow调用,因此其他Window不需要进行任何检查。

private void OpenChildWindow()
{
    if (this.OwnedWindows.OfType<ChildWindow>().Count() > 0)
    {
        ChildWindow Win = this.OwnedWindows.OfType<ChildWindow>().First();
        Win.Activate();
    }
    else
    {
        ChildWindow Win = new ChildWindow();
        Win.Owner = this;
        Win.Show();
    }
}

答案 4 :(得分:0)

使用界面有一种老式的方法可以做到这一点。我在Java中看到这很多,作为补偿没有代表的方法(如果我错了,请纠正我)。此方法将允许您检查是否已打开(任何类型)窗口。原始响应非常有效,但您也可以通过以下方式执行此操作:

创建界面

public interface IWindowTracker
{
    void WindowIsOpened();
    void WindowIsClosed();
}

在父级(从您打开的位置)实施界面:

public partial class MainWindow : Window, IWindowTracker

在构造函数中,接受IwindowTracker接口的对象。保存实例以供将来使用

    IWindowTracker windowTracker;
    public ProjectManager(IWindowTracker parentWindowTracker)
    {
        windowTracker = parentWindowTracker;

        InitializeComponent();
    }

设置对窗口跟踪器对象的调用

    protected override void OnActivated(EventArgs e)
    {
        windowTracker.WindowIsOpened();
        base.OnActivated(e);
    }

    protected override void OnClosed(EventArgs e)
    {
        windowTracker.WindowIsClosed();
        base.OnClosed(e);
    }

最后在父WPF窗口中实现IWindowTracker

    bool windowIsOpen = false;

    public void WindowIsOpened()
    {
        windowIsOpen = true;
    }

    public void WindowIsClosed()
    {
        windowIsOpen = false;
    }

这将允许您跟踪窗口是否仍然打开,如果是,则无需打开它的新实例:

        if (!windowIsOpen)
        {
            remoteProjectManager = new ProjectManager(this);
            remoteProjectManager.Show();
        }

        remoteProjectManager.Focus();

在一个关闭的窗口上调用show()似乎抛出一个异常,所以我的猜测是有一些其他方式或者如果你关闭了窗口,那么窗口在技术上是“被破坏”

这样做的好处是我可以检测窗口是否仍然打开并聚焦于它(以便它再次出现在前面)。

注意:有一个缺点,因为在此设置中它限制您一次只打开一个窗口(假设您的所有窗口都是这样实现的)。就我而言,我只想在主窗口旁打开一个窗口。

您可能还想检查您的窗口是否为空,考虑到它可能不是您必须打开的唯一窗口。