2012-02-23 168 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属性的值控制。

相关问题