1

現在、MEF インポートを介してビューモデルをロードするアプリケーションを設計しようとしています。

これまでのところ、辞書を介して各 vm データテンプレートを読み込んで、viewmodel から viewmodel に移動しました。

ナビゲートするたびに、シェル (MainWindow) のメイン contentPresenter のコンテンツを変更します。

ビューモデルの 1 つを使用すると、activeX コントロール (たとえば、アクロバット リーダーなど) の WindowFormHost を表示できます。WindowFormHost ではバインドが許可されていないため、ビューモデルで windowFormHost を作成し、ビューで ContentPresenter にバインドしました。

そして、ここで失敗します。同じビューモデルに戻ると、ビューが再度作成されます...「要素はすでに別の要素の子です」をスローします。エラー。

どうすればそれを防ぐことができますか? ビューがリロードされたときに WindowFormHost をアンロードする必要がありますか? または、ビューごとにインスタンスを 1 つだけ保持し、データ バインディングでコントロールを更新できるように、ビュー インスタンスを保持することはできますか? (メモリ消費のほうが良さそうです)。

ご協力いただきありがとうございます !

[編集]

読み込まれた辞書:

<DataTemplate x:Shared="False" DataType="{x:Type vm:DAVPDC3DVIAControlViewModel}">
    <vw:MyUserControl />
</DataTemplate>

意見 :

<DockPanel>
    <ContentControl Name="WFH3DVia" Content="{Binding Path=Control3DVIA, Mode=OneWay} </ContentControl>"
    <!--<WindowsFormsHost Name="WFH3DVia"></WindowsFormsHost>-->
</DockPanel>

VM (シングルトン、mef モジュール) :

[Export(typeof(IDAVPDC3DVIAControl))]
public partial class DAVPDC3DVIAControlViewModel : ViewModelBase, IViewModel, IPartImportsSatisfiedNotification

VM (メイン ウィンドウ)

[Export]
public class MainWindowViewModel : ViewModelBase, IPartImportsSatisfiedNotification

// CurrentUC はメイン ウィンドウ ビューをコントローラーのアクティブなビューモデルにバインドします

    public IViewModel CurrentUC
    {
        get
        {
            return myAddinManager.CurrentVM;
        }
    }

メインビュー:

コントローラー (イベント時にモジュールを表示) :

    private void ModuleReadyEventAction(string iModuleName)
    {
        if (null != this.Modules && this.Modules.Count() > 0)
        {
            foreach (var item in Modules)
            {
                IBaseModule ibasemodule = item as IBaseModule;
                if (null != ibasemodule)
                {
                    Type tp = ibasemodule.GetType();
                    if (0 == tp.Name.CompareTo(iModuleName))
                    {
                        CurrentVM = ibasemodule.GetViewModel();
                        break;
                    }
                }
            }
        }
    }
4

1 に答える 1

1

また、Prism v4 と MVVM を使用して WPF でプロジェクトに取り組んでいます (Unity を使用している場合を除く)。また、使用する必要があるコントロールが少なくとも 2 つあります。これらは、WindowsFormsHost でホストする必要がある Windows フォーム コントロールです。プロセスについての私の考えを説明させてください..

ビューのコードビハインドでコードを回避しようとしているように思えます。それが、WindowsFormsHost を ViewModel に移動していると私が考える唯一の理由です。これは根本的に間違ったアプローチだと思います。WindowsFormsHost は、グラフィカルな Windows フォーム コントロールを表示するために存在します。したがって、それはビューに属します!

これで、DataBinding の魅力がわかりました。WindowForms コントロールの多くの部分を DataBind できるようにしたいと思っていました。もちろん、WPF データ バインディングを受け入れるには、プロパティが依存オブジェクトの依存プロパティである必要があります。最も簡単な解決策は、不合理ではありませんが、ビューのコード ビハインドに Windows フォーム コントロールを構成するコードを追加することです。UI ロジックを ViewModel に追加することは、実際には MVVM デザイン パターンに違反しますが、コード ビハインドを追加することは違反ではありません。(場合によっては、これが最善の方法です)

この制限を回避しようとする可能性のあるハックを見てきました。データバインディングを挿入する「プロキシ」の使用、WindowsFormsHost の拡張、特定のホストされたコントロールのプロパティをラップする DependencyProperties の追加、またはリフレクションを使用してクラスを記述し、Windows フォーム バインディングをスローしようとすることを含みます。ただし、問題を完全に解決できるものは何もありません。たとえば、私の Windows フォーム コントロールには他のグラフィカル コンポーネントを含めることができ、それらのコンポーネントもバインドをサポートする必要があります。

最も簡単な方法は、ビューのコード ビハインドでビューをビューモデルと単純に同期することです。ビューモデルは、開いているファイルまたはドキュメント、ファイル名、タイトルなどを保持できますが、表示および表示関連のコントロールはビューに任せます。

最後に、あなたの質問に直接コメントさせてください。ビューとビューモデルを MEF コンテナーに登録する方法と、そのエラーが発生する理由を理解するためにナビゲートする方法を確認する必要があります。ビューまたはビューモデルのいずれかが複数回作成されているように思えますが、もう一方はそうではありません。これらはシングルトン型として登録されていますか? とにかく、ViewModel に WindowsFormsHost を含めないことについて私が言ったことを支持します。

于 2012-10-12T04:27:35.527 に答える