2012-02-23 110 views
0

我正在使用wmf模式在wpf中創建應用程序。我需要添加MEF到它。在使用mef的wpf應用程序中需要幫助

這是我的程序的基本架構。

我有一個主項目MefApplication。這隻有一個視圖MainWindow.xaml。這包含一個列表框和一個用戶控件。當應用程序運行時,它會加載模塊並在列表框中列出它們。點擊一個模塊會導致在用戶控件中顯示模塊。

現在爲模塊,它是一個WPF用戶控制庫。現在這個模塊將包含不同的視圖。一個視圖將會有一個按鈕,用於導航到模塊中的其他視圖。

現在我已經加載模塊並列出它們。點擊一個模塊會導致顯示模塊的第一個屏幕。但是當我點擊模塊視圖上的下一個按鈕時,沒有任何反應。我不知道如何去下一個視圖。以下是我的代碼。任何人都可以告訴我我哪裏出錯了。

MainWindow.xaml

<Window x:Class="MefApplication.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="40*"/> 
     <ColumnDefinition Width="80*"/> 
    </Grid.ColumnDefinitions> 
    <ListBox x:Name="listBox" Grid.Column="0" 
    ItemsSource="{Binding Modules}" SelectedItem="{Binding SelectedModule, Mode=TwoWay}" > 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding ModuleName}" /> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
    <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Content="{Binding UserInterface}"/> 
</Grid> 
</Window> 

MainWindow.xaml.cs

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = new MainWindowViewModel(); 
    } 
} 

MainWindowViewModel.cs

class MainWindowViewModel : INotifyPropertyChanged 
{ 
    #region NotifyOfPropertyChanged 
    #endregion 

    private string _path = "Path to Modules Dll Folder"; 
    public MainWindowViewModel() 
    { 
     Modules = GetModules(_path); 
     SelectedModule = Modules[0]; 
    } 

    public List<IMainModule> GetModules(string path) 
    { 
     var directoryCatalog = new DirectoryCatalog(path); 
     var container = new CompositionContainer(directoryCatalog); 
     var modules = container.GetExportedValues<IMainModule>().ToList(); 
     return modules; 
    } 

    private IMainModule selectedModule; 

    public List<IMainModule> Modules { get; set; } 

    public IMainModule SelectedModule 
    { 
     get { return selectedModule; } 
     set 
     { 
      if (value != selectedModule) 
      { 
       selectedModule = value; 
       NotifyOfPropertyChange("SelectedModule"); 
       NotifyOfPropertyChange("UserInterface"); 
      } 
     } 
    } 

    public UserControl UserInterface 
    { 
     get 
     { 
      if (SelectedModule == null) 
       return null; 
      return SelectedModule.UserInterface; 
     } 
    } 
} 

這是模塊接口。它包含模塊名稱和它的起始視圖。

public interface IMainModule 
{ 
    string Name { get; } 
    UserControl UserInterface { get; } 
} 

這是我的模塊之一。 ServerWindowModule。這會返回模塊(ServerWindow)中我的一個視圖的UserControl。

[Export(typeof(IMainModule))] 
class ServerWindowModule : IMainModule 
{ 
    public string Name 
    { 
     get { return "Server Module"; } 
    } 

    public UserControl _userInterface { get; set; } 
    public UserControl UserInterface 
    { 
     get { return _userInterface ?? (_userInterface = new ServerWindowView()); } 
    } 
} 

這是我的觀點之一。 ServerWindowView。

public partial class ServerWindowView : UserControl 
{ 
    public ServerWindowView() 
    { 
     InitializeComponent(); 
     DataContext = new ServerWindowViewModel(); 
    } 
} 

現在這裏是ViewModel for ServerWindowViewModel。

publicclassServerWindowViewModel : INotifyPropertyChanged 
{ 
    #region NotifyOfPropertyChanged 
    #endregionpublic ServerWindowViewModel() 
    { 
     LabelText = "Constructor set this."; 
    } 

    publicstring LabelText { get; set; } 

    privateICommand _nextCommand; 
    publicICommand NextCommand 
    { 
     get { return _nextCommand ?? (_nextCommand = newRelayCommand(NextFunction)); } 
    } 

    public void NextFunction() 
    { 
     LabelText = "Button set this."; 
     NotifyOfPropertyChange("LabelText"); 
     // TODO: Navigate to ServerValidation View 
     // Here i want to go to my next view(ServerValidationView). What should I write here. 
    } 
}   

現在在下一個按鈕功能我應該怎麼做,取代當前視圖到ServerValidationView。

如果有任何困惑,請詢問。

謝謝,

+0

爲'MainWindow.xaml'發佈相關的xaml – 2012-02-23 14:58:14

+0

@jberger你可以找到它的問題。我編輯過它。 – 2012-02-24 05:30:58

+0

'ContentPresenter'和'ContentControl'有時會扼殺我。你試過'ContentControl'嗎?當ListBox.SelectedItem改變時,MainWindowViewModel.UserInterface屬性是否被打開?最後,我建議不要在你的'IMainModule'中使用'UserControl'。相反,對於實現「IMainModule」的每種類型,在View中定義一個「DataTemplate」。 – 2012-02-24 15:15:00

回答

0

我目前正在做類似的事情。我不確定這是否是正確的處理方式,但我的設計是每個模塊都有自己的外殼。

例如,您的服務器窗口的第一個視圖將是一個具有內容展示器的Shell。要更改模塊中的視圖,我會更改模塊內演示者的內容。

這是基於我從http://www.ra-design.at/silverlight/mediaowl/

+0

我有一個包含多個視圖(用戶控件)的wpf用戶控件庫項目,我想通過按鈕事件瀏覽這些內容。 – 2012-02-27 10:48:35

0

Caliburn.Micro看到可以幫助您與這個或框架羅布艾森伯格提出了關於混合胡亂猜測。它使用依賴屬性

public static class View 
{ 
    public static DependencyProperty ModelProperty = 
     DependencyProperty.RegisterAttached(
      "Model", 
      typeof(object), 
      typeof(View), 
      new PropertyMetadata(ModelChanged) 
      ); 

    public static void SetModel(DependencyObject d, object value) 
    { 
     d.SetValue(ModelProperty, value); 
    } 

    public static object GetModel(DependencyObject d) 
    { 
     return d.GetValue(ModelProperty); 
    } 

    public static void ModelChanged(object sender, DependencyPropertyChangedEventArgs args) 
    { 
     if (args.NewValue == null || args.NewValue == args.OldValue) 
      return; 

     var vm = args.NewValue as IYourModuleProvidingUI; 
     var view = vm.UserInterface; 

     ((ContentControl)sender).Content = view; 
    } 
} 

和使用

<ContentControl Framework:View.Model="{Binding SelectedModule}" Padding="2,0,0,2"/> 

SelectedViewModel是提高INotifyPropertyChanged事件時,其價值已更改的屬性。那麼將顯示哪些內容由SelectedModule屬性的值控制。

相關問題