C# 在microsoft outlook加载项c上重新打开已关闭的WPF#

C# 在microsoft outlook加载项c上重新打开已关闭的WPF#,c#,wpf,xaml,outlook,add-in,C#,Wpf,Xaml,Outlook,Add In,我已经从Microsoft Outlook功能区中的一个按钮打开了一个WPF,用于我正在开发的加载项 private void _HandlerUserSettings(Office.CommandBarButton ctrl, ref bool cancel) { var windowUserSettings = new WpfUserSettings(); windowUserSettings.Show(); } 如果我从关闭按钮关闭WPF,如果我再次单击该按钮来处理窗口的

我已经从Microsoft Outlook功能区中的一个按钮打开了一个WPF,用于我正在开发的加载项

private void _HandlerUserSettings(Office.CommandBarButton ctrl, ref bool cancel)
{
    var windowUserSettings = new WpfUserSettings();
    windowUserSettings.Show();
}
如果我从关闭按钮关闭WPF,如果我再次单击该按钮来处理窗口的显示,它将不起作用。 我想关闭操作不仅仅是简单的隐藏,所以我的目标是覆盖关闭操作。我尝试了关闭xaml窗口的方法*WpfUserSettings\u Window\u 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>

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

据我所知,关闭功能将破坏窗口,因为您无法调用

 window.Show()
多次。这意味着窗口中的所有数据都已丢失。这是有意义的,因为窗口就像承载应用程序根的普通窗口。方法是在调用.Show()之前创建一个全新的窗口。但是,这会造成数据无法保存的问题。一旦打开新窗口,它将再次为空。虽然这不是你问题的一部分,但我认为有些人可能会觉得这很有用

为此,您需要使两个窗口相互对话以保存数据。父对象将保留子对象的数据,然后将其交给新创建的窗口重新填充

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

定义一个简单的接口。这将设置子窗口和父窗口之间的关系,并允许子窗口通知关闭,并将其数据返回安全保存

public interface IParentWindow
{
    void ChildClosed(SomeData data);
}
这将通知父窗口子窗口已关闭,现在该窗口可以保留数据,直到再次打开该窗口

将其分配给父窗口:

public partial class MainWindow : Window, IParentWindow
这将迫使您实现ChildClosed函数。在此之前,您会注意到我已经定义了一些数据。这可以是您喜欢的任何内容,只要两个窗口都使用它来来回发送数据

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

public struct SomeData
{
    public string name;
    public string email;
}
我们可以讨论为什么我把它做成一个结构,但这不是重点。如果你愿意的话,你可以把它做成一门课

接下来,实现child closed函数。为此,请在父类作用域中创建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)
现在我们可以保存从父级传递的数据了

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

在构造函数中

  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。

Hi@serguei fedorov,我不太清楚应该将
公共子窗口(SomeData data,IParentWindow父窗口)
放在哪里。你刚才说的是窗口构造函数,在我的WPF场景中,这是我的构造函数
public WpfUserSettings(){InitializeComponent();}
,但我不知道如何根据你的建议来管理它。你必须修改子windows构造函数以获取这些变量。这将是公共WpfUserSettings(SomeData,IParentWindow),记住SomeData对象应该由您定义。我想我必须问的问题是,当窗口关闭并再次打开时,是否要保存数据?如果不是,则放弃该数据对象。据我所知,您将需要接口来告诉父窗口子窗口已关闭(并设置bool,使其不再打开)。这是IParentWindow,在我的示例中,它与构造函数一起作为“This”传入。如果您希望我专门针对您的场景缩减答案,我可以为您发布第二个答案。
  protected override void OnClosed(EventArgs e)
  {
      parent.ChildClosed(myData);
      base.OnClosed(e);
  }