鉴于我有一个shell应用程序和一些使用Microsoft CompoisteWPF(Prism v2)的独立模块项目......
在接收命令时,模块创建新的ViewModel并通过区域管理器将其添加到区域.
var viewModel = _container.Resolve<IMyViewModel>();
_regionManager.Regions[RegionNames.ShellMainRegion].Add(viewModel);
Run Code Online (Sandbox Code Playgroud)
我想我可以在模块中创建一个资源字典并设置一个数据模板来显示已加载的视图模型类型的视图(参见下面的xaml).但是当视图模型添加到视图中时,我得到的只是打印出的视图模型命名空间.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Modules.Module1.ViewModels"
xmlns:vw="clr-namespace:Modules.Module1.Views"
>
<DataTemplate DataType="{x:Type vm:MyViewModel}">
<vw:MyView />
</DataTemplate>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
编辑:
我可以通过添加到App.xaml来实现它
<Application.Resources>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Module1;component/Module1Resources.xaml"/>
<ResourceDictionary Source="pack://application:,,,/Module2;component/Module2Resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)
这很好,但这意味着在创建新模块时,需要添加App.xaml文件.我正在寻找的是模块的一种方式,因为它们加载动态添加到Application.Resources.这可能吗?
在Composite WPF(Prism)中,当向IRegionManger集合添加模块时,使用IRegion.Add和IRegionManager.RegisterViewWithRegion有什么区别?
IRegion.Add
public void Initialize()
{
_regionManager.Regions["MainRegion"].Add( new ModuleAView() );
}
Run Code Online (Sandbox Code Playgroud)
IRegionManager.RegisterViewWithRegion
public void Initialize()
{
_regionManager.RegisterViewWithRegion( "MainRegion", typeof( ModuleAView ) );
}
Run Code Online (Sandbox Code Playgroud) 我有一个课程,通过PRISMs事件聚合器订阅一个事件.
由于这里提到的模拟事件聚合器有点困难,我只是实例化一个真实聚合器并将其传递给被测系统.
在我的测试中,我然后通过该聚合器发布事件,然后检查我的测试系统如何对它做出反应.由于事件将在生产期间由FileSystemWatcher引发,我想通过订阅UIThread来使用自动分派,因此我可以在引发事件后更新我的UI.
问题是,在测试期间,除非我没有订阅UIThread,否则事件永远不会在被测系统中被注意到.
我正在使用MSpec进行测试,我通过TDD.Net从VS2008内部运行.添加[RequiresSta]到我的测试类没有帮助
有没有人有一个解决方案,这使我免于在测试期间更改ThreadOption(例如通过属性 - 这是一个丑陋的黑客)???
如果我不将我的应用程序拆分成不同的模块(否则我会认为Prism将会成为可行的方法)我应该使用Prism吗?
我知道Prism提供了一个方便的实现ICommand(我可以在代码页中自己完成)并给我们IEventAggregator但是所有Bootstrapper,Shell,ModuleCatalog的东西真的有帮助吗?
为什么不使用MVVM模式(没有Prism)来分离你的顾虑,这样你的应用程序才是可测试的,鲍勃是你的叔叔!
PRISM和MEF等框架使得从多个可组合组件中设计复杂的应用程序变得非常容易.一个常见的例子是插件架构,其中应用程序shell可以通过插件UI组件进行动态重新配置(例如,通过将DLL删除到Plug-ins目录中).
这一切都很好,但是当调用网络服务时,在Can Prism中发现的Vaccano 是模块化的吗?在某些情况下,每个插件都需要自己的配置集--WCF绑定是一个典型示例,但还有许多其他具有类似需求的场景(日志记录,数据库连接等).
所以,正如我所看到的,我们的选择是:
App.configshell应用程序(正如Vaccano所提到的那样打破了这个模型的整个封装和部署优势),或者这些选项都不是理想选择,但它们是解决方法.但是,理想情况是每个插件DLL都有自包含配置(例如嵌入式资源文件)或Xxx.dll.config文件,并且App.config在运行时动态地将这些XML配置片段中的每一个合并到shell应用程序的配置中.这让人联想到合并的方式Machine.config和App.config文件.
因此,我的问题是:有没有人遇到过任何现有的框架或技术,可以用来将复合配置文件动态合并到容器应用程序的进程内配置中?我很惊讶不要将此视为PRISM或MEF的一部分,因此稍微警惕发布此问题以防我错过了一些明显的事情 - 如果是这样,请悄悄发布相关链接:)
我在该领域的经验非常少,我正在编写一个使用MVVM与WCF后端通信的WPF智能客户端应用程序,并且我真的很难从所有信息中做出正确的决策.这引出了一系列问题,我希望在这方面有更多经验的人可以解决这些问题.
例如,其中一个屏幕将允许输入订单并向订单添加订单行.
什么用作模型?
在WCF服务上,我有以下简化的DTO:
public OrderDTO
{
string orderDetails { get; set; }
List<OrderLineDTO> OrderLines { get; set; }
}
public OrderLineDTO
{
int customerId { get; set; }
int productId { get; set; }
double quantity { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和WCF服务有以下方法:
public OrderService Order
{
CreateOrderResponse CreateOrder(OrderDTO order)
}
Run Code Online (Sandbox Code Playgroud)
在我的WPF智能客户端中,我有一个对DTO的引用,但显然它没有实现,INotifyPropertyChanged因为它纯粹是为了传输.
问题
建议的方法是将这些DTO转换为INotifyPropertyChanged使用Automapper或类似方法实现的模型吗?或者DTO应该直接在ViewModel中用作模型?
在视图模型之间进行通信
目前,我有一个带有ViewModels 和2的标签(Order和OrderLines)的订单视图.在订单选项卡上,我有一个包含客户ID和名称.当我选择客户时,我需要告知客户已被选中,以便仅显示属于该客户的产品.OrderViewModelOrderLineViewModelComboBoxOrderViewOrderLineViewComboBox
问题
在这种情况下如何OrderViewModel沟通OrderLineViewModel?
添加订单行并应用逻辑/业务规则
由于服务器级应用程序将由多个客户端使用,例如PC,移动设备..我想确保所有业务规则都应用于服务器级应用程序.例如,添加订单行时.如果是某种产品类型,只有在客户有特定认证的情况下才能添加.
但是,我所读到的关于MVVM的所有内容都表明该模型适用于业务规则和行为 …
我陷入了一个看似普遍的要求.我有一个WPF Prism(用于MVVM)应用程序.我的模型实现了IDataErrorInfo以进行验证.该IDataErrorInfo的非数值属性的伟大工程.但是,对于数字属性,如果用户输入无效字符(非数字),则数据甚至不会到达模型,因为wpf无法将其转换为数字类型.
所以,我不得不使用WPF ValidationRule为用户提供一些有意义的无效数字条目消息.视图中的所有按钮都绑定到棱镜的DelegateCommand(在视图模型中),按钮的启用/禁用在View Model本身中完成.
现在,如果某个TextBox的wpf ValidationRule失败,如何将此信息传递给View Model,以便它可以适当地禁用视图中的按钮?
我在WPF应用程序中使用PRISM 5.而在我的应用程序壳牌观点有两个区域,为A和区域应该安放A包含一个弹出考虑它(PRISM 5交互功能是用来显示弹出式).
当我在视图的构造函数中创建弹出视图模型的实例时,应用程序正在工作.
工作代码
public PopupView()
{
InitializeComponent();
this.DataContext = new PopupViewModel(); // Working code
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试使用依赖注入创建视图模型实例时.应用程序InitializeComponent();在父视图(视图A)上失败 .
DI不工作代码
public PopupView(PopupViewModel viewModel)
{
InitializeComponent(); // Failing in AView initialze
// before reaching here
this.DataContext = viewModel;
}
Run Code Online (Sandbox Code Playgroud)
在module/bootstrapper中查看模型注册
container.RegisterType<AViewModel>();
Run Code Online (Sandbox Code Playgroud)
发生了错误
NULLReference发生异常
Stacktrace(编辑问题)
at System.DefaultBinder.BindToMethod(BindingFlags bindingAttr, MethodBase[] match, Object[]& args, ParameterModifier[] modifiers, CultureInfo cultureInfo, String[] names, Object& state)
at MS.Internal.Xaml.Runtime.DynamicMethodRuntime.CreateInstanceWithCtor(Type type, Object[] args)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstance(XamlType xamlType, Object[] args)
at MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.CreateInstance(XamlType xamlType, Object[] args)
at System.Xaml.XamlObjectWriter.Logic_CreateAndAssignToParentStart(ObjectWriterContext ctx)
at …Run Code Online (Sandbox Code Playgroud) 在WPF项目(带棱镜)中,我们使用UnityDI框架.
最近,在我们合并了两个大分支机构之后,我们无法启动我们的应用程序StackOverflowException.由于异常的性质,我们无法得到他的调用堆栈或当前值,我们只是因为命名空间而导致问题是来自Unity.
我们花了5个多小时才找到问题所在:
简化:
我们有3-4个服务(A,B,C和D),每个服务都有一个实现,并且在某些时候,服务A需要服务B,这需要服务C,这需要服务D ,这需要服务A).基本上是循环引用.
我们想知道是否有可能添加一些Unity尝试使用实现X解决服务A的日志,并且需要解析服务B,...
这将有助于我们调试此问题,直接查看哪些服务涉及此循环引用.
反正有没有实现这个目标?
更新:焦点变成MVVM而不是实际问题,所以我正在更新它.
我有一个问题CanExecute了DelegateCommand.它在我打电话之前没有更新RaiseCanExecuteChanged,这是期望的行为吗?

我在这里上传了一个简单的示例项目来重现这个问题:http://dl.dropbox.com/u/39657172/DelegateCommandProblem.zip
问题是这个,我有两个Buttons这样的.一个是绑定Command到一个RelayCommand实现,另一个绑定到Prism的实现DelegateCommand
<Button Command="{Binding DelegateSaveCommand}"/>
<Button Command="{Binding RelaySaveCommand}"/>
Run Code Online (Sandbox Code Playgroud)
ViewModel ICommands
DelegateSaveCommand = new DelegateCommand(Save, CanSaveDelegate);
RelaySaveCommand = new RelayCommand(param => Save(), param => CanSaveRelay);
Run Code Online (Sandbox Code Playgroud)
和CanExecute方法/谓词
public bool CanSaveDelegate()
{
return HasChanges;
}
public bool CanSaveRelay
{
get { return HasChanges; }
}
Run Code Online (Sandbox Code Playgroud)
两人都在使用该物业HasChanges.何时HasChanges更新,仅CanSaveRelay更新.这是它的意思吗?