2012-01-13 2 views
3

私はWPF + PRISM + MVVMアプリケーションでダイアログウィンドウを実装しようとしています。今はサンプルサービスを作成していて、各モジュールはこのサービスを使用してウィンドウ内の任意のビューを表示できますが、この問題は非常に珍しいものであり、動作させることはできません。ダイアログの実装が失敗しました。すでに別の要素の論理的な子です。

ここにウィンドウサービスの契約があります。

public interface IUiDialogueService : IDisposable 
{ 
    void Show<TView>(TView view) where TView : IViewModel; 
} 

public class UiDialogueService : IUiDialogueService, IDisposable 
{ 
    private Window _dialogueWindow; 

    #region Implementation of IUiDialogueService 

    public void Show<TView>(TView view) where TView : IViewModel 
    { 
     _dialogueWindow = new Window 
           { 
            SizeToContent = SizeToContent.WidthAndHeight, 
            ResizeMode = ResizeMode.NoResize, 
            ShowInTaskbar = false, 
            Content = view.View 
           }; 
     _dialogueWindow.ShowDialog(); 
     _dialogueWindow = null; 

    } 
} 

モジュールからウィンドウサービスにアクセスする方法は次のとおりです。

private void OnStartWizard() 
    { 
     _dialogueService.Show(ServiceLocator.Current 
        .GetInstance<IOrgManagementOrganizatioSetupViewViewModel>()); 
    } 

すべてがとき、私最初に開いた窓うまく動作しますが、私はそれを閉じた後と同じオープンまたは他のビューウィンドウ内に、私は復活例外次

指定された要素は、すでに別の要素の論理的な子です。最初に切断します。

この例外は次のコードによってスローされます。

 _dialogueWindow = new Window 
           { 
            SizeToContent = SizeToContent.WidthAndHeight, 
            ResizeMode = ResizeMode.NoResize, 
            ShowInTaskbar = false, 
            Content = view.View 
           }; 

誰もがここで間違って何が起こっているかを説明し、MVVMのarchitectur子(対話)ウィンドウを取得するために任意のより良い方法はありますか? Showの最後の行の前に次のコードを追加し

答えて

3

試してみてください。

_dialogueWindow.Content = null; 

Showは次のようになります。

public void Show<TView>(TView view) where TView : IViewModel 
{ 
    _dialogueWindow = new Window 
          { 
           SizeToContent = SizeToContent.WidthAndHeight, 
           ResizeMode = ResizeMode.NoResize, 
           ShowInTaskbar = false, 
           Content = view.View 
          }; 
    _dialogueWindow.ShowDialog(); 
    _dialogueWindow.Content = null; 
    _dialogueWindow = null; 
} 
+0

これはうまくいくようですが、これはサンプル実装であり、このウィンドウに何かを返すか、イベントを閉じる際にコールバック関数を呼び出すとは思いません。コールバックメソッドまたはダイアログ結果オプションでこのシナリオを実装する良い例をいくつか提供してください。 –

+0

これはあなたの提案の例外がコードによってスローされたものですあなたの答えは答えとしてマークしますが、コールバックに関する詳細情報を提供してください。 –

+0

@Rati_Ge:例外と何が関係しているのかわかりません。コールバックについて新しい質問を作成してください。あなたの役に立つ答えが得られる可能性が高いので、あなたの方がよいでしょう。必要に応じて、この質問にリンクしてコンテキストを設定することができます。 –

1

WPFの各要素は一つだけの親要素に属することができます。要素が表示されていなくても(またはこれ以上表示されなくても)、親子関係が維持されます。要素に新しい親を与えたい場合は、まずそれを古い親から削除する必要があります。

あなたのケースでは、Show()では、あなたのビューにウィンドウのコンテンツを設定しています。そのウィンドウが表示された後も、ビューはそのウィンドウの子です。別のウィンドウで同じビューを表示しようとすると、その例外が発生します。

最も良い方法は、ウィンドウからビューを削除することです(Daniel Hilgarthの答えに記載されています)。また、ビューに親がすでに存在するかどうかを確認し、手動でその親から手動で削除することもできます。

関連する問題