0

開発中のアドイン用に、Microsoft Outlook のリボンのボタンから WPF を開きました。

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

閉じるボタンからWPFを閉じると、ボタンをもう一度クリックしてウィンドウの表示を処理すると、機能しません。閉じるアクションは単純な非表示以上のことを行うと思うので、私の目標は閉じるアクションをオーバーライドすることです。xaml ウィンドウのClosingメソッド *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() を呼び出す前に、まったく新しいウィンドウを作成するだけです。ただし、これにより、データが保存されないという問題が発生します。新しいウィンドウを開くと、再び空白になります。これはあなたの質問の一部ではありませんが、これが役立つと思う人もいると思います。

このためには、データを保存するために 2 つの 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);
  }

すすぎと繰り返し!

ノート; 最初のオープンでは、データを保存する前に、null 変数を持つオブジェクトを渡すことができます。次に、子ウィンドウで、これに基づいて UI を更新する必要があるかどうかを判断できます。

于 2013-09-27T07:01:33.690 に答える