在 Microsoft Outlook Addin C# 上重新打开已关闭的 WPF

本文关键字:WPF 新打开 Outlook Microsoft Addin | 更新日期: 2023-09-27 18:33:05

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

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>

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

在 Microsoft Outlook Addin C# 上重新打开已关闭的 WPF

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

 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。