簡體   English   中英

WPF,MEF,Prism-如何在Shell中設置DataContext

[英]WPF,MEF,Prism - How to set DataContext in shell

我將WPF / PRISM / MEF用於桌面應用程序。

這是一個簡單的測試應用程序,具有三個區域。 視圖在外部模塊中定義。

看來我需要設置外殼DataContext。 因此,將其設置為如下所示的視圖模型-應用程序運行正常。

我對做出明確的定義不滿意。 在初始化過程中,是否無法加載某些模塊,並找到一些視圖並將其分配給我的Shell的DataContext,這是不可能的嗎? 我在哪里可以找到文檔-我一定在開發人員指南(和示例應用程序)中錯過了它。 或者,有人提出建議嗎?

Shell.xaml:

<Window x:Class="TestMenuTaskbarDT.Shell"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:prism="http://www.codeplex.com/prism"   

  xmlns:local_viewmodels="clr-namespace:TestMenuTaskbarModuleMain.ViewModels;assembly=TestMenuTaskbarModuleMain"
    . . .
>

  <Window.InputBindings>
    <KeyBinding Key="S" Modifiers="Control" Command="{Binding Path=CloseProjectCommand}" />
    <KeyBinding Key="O" Modifiers="Control" Command="{Binding Path=OpenProjectCommand}" />
  </Window.InputBindings>
  <StackPanel>
    <ItemsControl Name="MainMenuRegion" prism:RegionManager.RegionName="MainMenuRegion" />
    <ItemsControl Name="MainToolbarRegion" prism:RegionManager.RegionName="MainToolbarRegion" />
    <ItemsControl Name="MainContentRegion" prism:RegionManager.RegionName="MainContentRegion" />
  </StackPanel>
  <!-- How does one set the datacontext, when it should be dynamically loaded? -->
  <Window.DataContext>
    <local_viewmodels:MainWindowViewModel />
  </Window.DataContext>

</Window>

(或者應該將local_viewmodels ...放在資源中並以某種方式設置在那里?)

然后可以在Bootstrapper中放入以下內容嗎? 還是有完全不同的技術?

Bootstrapper.cs:

. . .
class Bootstrapper : MefBootstrapper
{
    . . .
  protected override IModuleCatalog CreateModuleCatalog()
  {
      // All dlls are expected to reside in the same directory as the *.exe
      return new DirectoryModuleCatalog() { ModulePath = System.AppDomain.CurrentDomain.BaseDirectory };           
  }

  protected override void ConfigureAggregateCatalog()
  {
      base.ConfigureAggregateCatalog();
      this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
      // Module registration remains the same *IT* registers the views with the region catalog
      this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(TestMenuTaskbarModuleMain.TestMenuTaskbarModuleMain).Assembly));
  }
    . . .

  protected override void InitializeShell()
  {
    base.InitializeShell();
    Application.Current.MainWindow = (Window)this.Shell;
    // Is something like the following possible?
      _MyBaseViewModel = GetAViewModelSomehowFromAModule("MyViewModelKey");
      Application.Current.MainWindow.DataContext = _MyBaseViewModel;
    //
    Application.Current.MainWindow.Show();                 // Displays MainWindow

    }

在我的Shell.xaml.cs中,將定義以下屬性:

[Import]
ShellViewModel ViewModel
{
    set
    {
        this.DataContext = value;
    }
}

然后在我的ShellViewModel類中,構造函數將像這樣被裝飾...

[Export]
public class ShellViewModel

因此,依靠MEF組合導入/導出屬性來實現DataContext設置。 這是一個簡化的示例,但您可能需要進一步了解有關構圖純度錯誤等問題。

如果我了解Dynamoid,則應使用以下內容:

namespace TestMenuTaskbarDT
{     
  [Export]
  public partial class Shell : Window
  {
    [ImportingConstructor] public Shell([Import("ShellViewModel")]object aShellViewModel)
    {
        InitializeComponent();
        //NOTE: DataContext is magically set from the imported object "aShellViewModel."
        // I assume MEF uses Reflection to magically resolve all internal references.
        DataContext = aShellViewModel;
    }

    /* removed, ImportingConstructor does it all in one step.
    Note: DataContext is magically set from "value."
    [Import("ShellViewModel")]
    public object ViewModel
    {
        set { this.DataContext = value; }
    }
     */
}

}

顯然,帶有初始化的單步構造比先構造然后初始化的兩步形式簡單。 (因此,人們應該單擊動態注釋以給予他應有的待遇-不僅是出於他的暗示,而且是出於他對表達自己觀點的熱情。)

(這里剩下的唯一一件事就是讓它在設計時正確顯示-但這是另外一個困惑。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM