在使用mef的wpf应用程序中需要帮助吗
我正在wpf中按照MVVM模式制作一个应用程序。我需要加入MEF 这是我的程序的基本架构 我有一个主要项目mefaapplication。这只有一个视图MainWindow.xaml。它包含一个列表框和一个用户控件。当应用程序运行时,它加载模块并在列表框中列出它们。单击模块会导致在usercontrol中显示模块 现在对于模块来说,它是一个WPF用户控制库。现在,这个模块将包含不同的视图。一个视图将有一个按钮,用于导航到模块内的其他视图 现在我已经加载了模块并将它们列了下来。单击模块会显示模块的第一个屏幕。但是,当我单击模块视图上的“下一步”按钮时,什么也没有发生。我不知道如何去下一个视图。下面是我的代码。谁能告诉我哪里出了问题 MainWindow.xaml在使用mef的wpf应用程序中需要帮助吗,wpf,mvvm,mef,Wpf,Mvvm,Mef,我正在wpf中按照MVVM模式制作一个应用程序。我需要加入MEF 这是我的程序的基本架构 我有一个主要项目mefaapplication。这只有一个视图MainWindow.xaml。它包含一个列表框和一个用户控件。当应用程序运行时,它加载模块并在列表框中列出它们。单击模块会导致在usercontrol中显示模块 现在对于模块来说,它是一个WPF用户控制库。现在,这个模块将包含不同的视图。一个视图将有一个按钮,用于导航到模块内的其他视图 现在我已经加载了模块并将它们列了下来。单击模块会显示模块的
<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>
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;
}
}
}
这是我的一个模块。服务器窗口模块。这将返回模块(ServerWindow)中我的一个视图的用户控制权
这是我的观点之一。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.
}
}
现在在下一个按钮函数中,我应该做什么来将当前视图替换为ServerValidationView
如果有任何混淆,请询问
谢谢,我目前正在做类似的事情。我不确定这是否是正确的处理方式,但我的设计是每个模块都有自己的外壳 例如,服务器窗口的第一个视图将是一个具有内容演示器的Shell。要更改模块内的视图,我将更改模块内演示者上的内容 这是一个基于我在中看到的猜测,它可以帮助您实现这个或Rob Eisenberg在Mix上介绍的框架。它使用依赖属性
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属性的值控制。为MainWindow发布相关xaml。xaml
@jberger您可以找到它。我已经编辑过了。ContentPresenter
和ContentControl
有时会让我窒息。您是否尝试了ContentControl
?当ListBox.SelectedItem
发生更改时,MainWindowViewModel.UserInterface
属性是否会被命中?最后,我建议不要在IMainModule
中使用UserControl
。相反,对于实现IMainModule
的每种类型,请在视图中定义一个DataTemplate
。我有一个wpf用户控件库项目,其中包含多个视图(用户控件),我希望通过按钮事件浏览这些视图。
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.
}
}
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"/>