【发布时间】:2012-02-23 13:22:14
【问题描述】:
我正在按照 MVVM 模式在 wpf 中制作应用程序。我需要在其中添加 MEF。
这是我的程序的基本架构。
我有一个主项目 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; }
}
这是我的模块之一。服务器窗口模块。这将返回模块 (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()); }
}
}
这是我的观点之一。服务器窗口视图。
public partial class ServerWindowView : UserControl
{
public ServerWindowView()
{
InitializeComponent();
DataContext = new ServerWindowViewModel();
}
}
现在这里是 ServerWindowViewModel 的 ViewModel。
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.
}
}
现在在 Next 按钮功能上,我应该怎么做才能将当前视图替换为 ServerValidationView。
如果有任何困惑,请询问。
谢谢,
【问题讨论】:
-
发布
MainWindow.xaml的相关xaml -
@jberger 你可以找到它。我已经编辑过了。
-
ContentPresenter和ContentControl有时会让我窒息。你试过ContentControl吗?当ListBox.SelectedItem发生变化时,MainWindowViewModel.UserInterface属性会受到影响吗?最后,我建议不要在您的IMainModule中使用UserControl。相反,对于实现IMainModule的每种类型,在您的视图中定义一个DataTemplate。