0

我有一个从 Microsoft Outlook 功能区中的按钮打开的 WPF,用于我正在开发的插件。

private void _HandlerUserSettings(Office.CommandBarButton ctrl, ref bool cancel)
{
    var windowUserSettings = new WpfUserSettings();
    windowUserSettings.Show();
}

如果我从其关闭按钮关闭 WPF,如果我再次单击该按钮来处理窗口的显示,它就不起作用。我想关闭动作不仅仅是一个简单的隐藏,所以我的目标是覆盖关闭动作。我尝试使用我的 xaml 窗口的关闭方法 *WpfUserSettings_Window_Closing*:

<Window x:Class="TrainingForgeOutlookAddin.View.WpfUserSettings"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        mc:Ignorable="d" 
        d:DesignHeight="350" d:DesignWidth="700" Title="User Settings"
        WindowStartupLocation="CenterScreen" Loaded="WpfUserSettings_OnLoaded"
        Closing="WpfUserSettings_Window_Closing">
 ....
</Window>

你有什么建议或如何阅读,我没有找到吗?谢谢你

4

1 回答 1

0

据我所知,关闭函数会破坏窗口,因为您无法调用

 window.Show()

多次。这意味着窗口中的所有数据都已丢失。这是有道理的,因为 Window 就像托管应用程序根目录的普通窗口一样。这样做的方法是在调用 .Show() 之前简单地创建一个全新的窗口。但是,这会产生您的数据未保存的问题。打开新窗口后,它将再次为空白。虽然这不是您问题的一部分,但我认为有些人可能会觉得这很有用。

为此,您需要使两个 Windows 相互通信以保存数据。父级将保留子级的数据,然后将其提供给新创建的窗口以重新填充。

有些人更喜欢委托,我更喜欢为此使用接口。

定义一个简单的接口。这建立了子窗口和父窗口之间的关系,并允许子窗口通知它正在关闭并将其数据返回以进行安全保存。

public interface IParentWindow
{
    void ChildClosed(SomeData data);
}

这将通知父窗口子窗口已关闭,现在窗口可以保留数据,直到窗口再次打开。

将此分配给父窗口:

public partial class MainWindow : Window, IParentWindow

这将迫使您实现 ChildClosed 功能。在我们这样做之前,您会注意到我已经定义了 SomeData。只要两个窗口都使用它来回发送数据,这可以是您喜欢的任何内容。

对我来说, SomeData 的实现如下所示:

public struct SomeData
{
    public string name;
    public string email;
}

我们可以讨论为什么我把它做成一个结构,但这不是重点。如果你愿意,你可以把它变成一堂课。

接下来,实现子关闭功能。为此,请在父类范围内创建 SomeData 对象:

 SomeData lastWindowData;

这个函数可以告诉父母如何保留它的数据

 public void ChildClosed(SomeData data)
 {
     lastWindowData.email = data.email;
     lastWindowData.name = data.name;
 }

好的,在我们进入子窗口之前,我们必须实现窗口的打开。因为,正如我所发现的(请告诉我还有另一种解决方法?),窗口一旦关闭就无法重新打开。这意味着我们必须创建一个全新的窗口。将其放入您的活动中,以打开窗口为准:

 childWindow = new ChildWindow(lastWindowData, this);
 childWindow.Show();

正如您将注意到的,窗口获取数据和“this”,这是我们的父窗口。它这样做是为了能够在关闭之前回调父窗口并允许父窗口保存数据。

让我们移动到子窗口。

修改子窗口的构造函数以接受 SomeData 和 IParentWindow 对象。回过头来看,IParentWindow 是打开孩子的窗口。

  public ChildWindow(SomeData data, IParentWindow parent)

现在我们可以保存从父级传递的数据!

为您的窗口定义一个数据持有者,它是一些 SomeData 对象(在子窗口类中)

  SomeData myData;

并在构造函数中

  myData.email = data.email;
  myData.name = data.name;

所以我们可以重新填充所有内容。你可以自己弄清楚重新人口的部分。这样,窗口现在已经接收到之前关闭的子窗口的数据,我们可以恢复它,就好像它是之前的窗口一样!

当你在窗口中做某事(可以是任何地方,任何地方),你可以改变你的数据。假设我分配了一个名称和电子邮件:

  myData.email = "gordon@freeman.com";
  myData.name = "Gordon Freeman";

最后但同样重要的是,一旦我们关闭子窗口,我们可以通知父窗口子窗口正在关闭,我们可以将新更新的数据再次保存!

  protected override void OnClosed(EventArgs e)
  {
      parent.ChildClosed(myData);
      base.OnClosed(e);
  }

冲洗并重复!

笔记; 对于第一次打开,在您保存任何数据之前,您可以传入一个带有空变量的对象。然后,您可以在子窗口中根据此确定是否需要更新 UI。

于 2013-09-27T07:01:33.690 回答