POCO(PlainOldCLRObjects)视图模型简化并加快了开发过程。 POCO视图模型允许您:将可绑定属性定义为简单的自动实现的属性。创建在运行时用作命令的方法。使属性和方法实现特定于MVVM的接口。 这允许您创建干净、简单、可维护和可测试的MVVM代码,POCO视图模型与任何WPF控件完全兼容。 您可以使用在编译时生成的视图模型在编译时为您的视图模型生成样板代码。 DevExpressUniversalSubscription官方最新版免费下载试用,历史版本下载,在线文档和帮助文件下载慧都网Services DevExpressMVVM框架包括Services机制,下面的代码示例演示了如何访问MessageBox服务。 CusingDevExpress。Mvvm。POCO;。。。publicclassLoginViewModel{publicIMessageBoxServiceMessageBoxService{get{returnthis。GetServiceIMessageBoxService();}}}依赖注入 要将视图绑定到视图模型,请创建解析正确ViewModel类型的MarkupExtension: CpublicclassDISource:MarkupExtension{publicstaticFuncType,object,string,objectResolver{get;set;}publicTypeType{get;set;}publicobjectKey{get;set;}publicstringName{get;set;}publicoverrideobjectProvideValue(IServiceProviderserviceProvider)Resolver?。Invoke(Type,Key,Name);} 在应用程序启动时注册解析器: CprotectedoverridevoidOnStartup(StartupEventArgse){base。OnStartup(e);DISource。ResolverResolve;}objectResolve(Typetype,objectkey,stringname){if(typenull)returnnull;if(key!null)returnContainer。ResolveKeyed(key,type);if(name!null)returnContainer。ResolveNamed(name,type);returnContainer。Resolve(type);} 通过以下方式在XAML中指定DataContext: XAMLDataContext{common:DISourceTypecommon:MainViewModel} 要在依赖注入容器中使用POCO视图模型,请利用ViewModelSource。GetPOCOType方法注册在运行时生成的POCO类型: Ccontainer。RegisterType(typeof(IMainViewModel),ViewModelSource。GetPOCOType(typeof(MainViewModel)));查看模型父子关系 POCO视图模型可以通过父子关系相互关联。这是通过ISupportParentViewModel接口实现的,该接口在您使用ViewModelSource类创建POCO对象时自动实现。通过这个接口,子视图模型可以访问在主视图模型中注册的服务。自动IDataErrorInfo实现 IDataErrorInfo接口是WPF中数据验证的标准机制,您可以使用此接口为每个单独的属性或整个对象定义验证规则。POCO机制允许您基于定义的属性或FluentAPI自动实现IDataErrorInfo接口。 要启用此功能,请为您的视图模型应用POCOViewModel属性并将POCOViewModel。ImplementIDataErrorInfo参数设置为True。 CAttributebasedapproach〔POCOViewModel(ImplementIDataErrorInfotrue)〕publicclassLoginViewModel{〔Required(ErrorMessagePleaseentertheusername。)〕publicvirtualstringUserName{get;set;}}FluentAPI〔POCOViewModel(ImplementIDataErrorInfotrue)〕〔MetadataType(typeof(LoginViewModel。Metadata))〕publicclassLoginViewModel{publicclassMetadata:IMetadataProviderLoginViewModel{voidIMetadataProviderLoginViewModel。BuildMetadata(MetadataBuilderLoginViewModelbuilder){builder。Property(xx。UserName)。Required(()Pleaseentertheusername。);}}publicvirtualstringUserName{get;set;}} 当ViewModelSource生成ViewModel的后代时,它会实现IDataErrorInfo接口,如下所示: CpublicclassLoginViewModel:IDataErrorInfo{。。。stringIDataErrorInfo。Error{get{returnstring。Empty;}}stringIDataErrorInfo。this〔stringcolumnName〕{get{returnIDataErrorInfoHelper。GetErrorText(this,columnName);}}} IDataErrorInfoHelper类允许您根据指定的DataAnnotation属性或FluentAPI获取错误。 下面的代码示例演示了如何使用POCO机制来实现IDataErrorInfo接口。 MainView。xamlUserControlx:ClassExample。View。MainViewxmlnshttp:schemas。microsoft。comwinfx2006xamlpresentationxmlns:xhttp:schemas。microsoft。comwinfx2006xamlxmlns:dhttp:schemas。microsoft。comexpressionblend2008xmlns:mchttp:schemas。openxmlformats。orgmarkupcompatibility2006xmlns:dxhttp:schemas。devexpress。comwinfx2008xamlcorexmlns:dxehttp:schemas。devexpress。comwinfx2008xamleditorsxmlns:dxmvvmhttp:schemas。devexpress。comwinfx2008xamlmvvmxmlns:ViewModelclrnamespace:Example。ViewModelmc:Ignorabledd:DesignHeight400d:DesignWidth400DataContext{dxmvvm:ViewModelSourceTypeViewModel:MainViewModel}UserControl。Resourcesdxmvvm:BooleanNegationConverterx:KeyBooleanNegationConverterUserControl。ResourcesGridStackPanelOrientationVerticalMargin10dxe:ValidationService。IsValidationContainerTruex:NamevalidationContainerGridGrid。ColumnDefinitionsColumnDefinitionWidthColumnDefinitionWidthGrid。ColumnDefinitionsStackPanelOrientationVerticalMargin0,0,4,6TextBlockTextNameMargin6,2,0,2dxe:TextEditNullTextFirstEditValue{BindingFirstName,ValidatesOnDataErrorsTrue,UpdateSourceTriggerPropertyChanged}StackPanelStackPanelOrientationVerticalMargin4,0,0,6Grid。Column1TextBlockTextMargin6,2,0,2dxe:TextEditNullTextLastEditValue{BindingLastName,ValidatesOnDataErrorsTrue,UpdateSourceTriggerPropertyChanged}StackPanelGridStackPanelOrientationVerticalMargin0,0,0,6TextBlockTextEmailMargin6,2,0,2dxe:TextEditEditValue{BindingEmail,ValidatesOnDataErrorsTrue,UpdateSourceTriggerPropertyChanged}StackPanelStackPanelOrientationVerticalMargin0,0,0,6TextBlockTextPasswordMargin6,2,0,2dxe:PasswordBoxEditEditValue{BindingPassword,ValidatesOnDataErrorsTrue,UpdateSourceTriggerPropertyChanged}StackPanelStackPanelOrientationVerticalMargin0,0,0,6TextBlockTextConfirmPasswordMargin6,2,0,2dxe:PasswordBoxEditEditValue{BindingConfirmPassword,ValidatesOnDataErrorsTrue,UpdateSourceTriggerPropertyChanged}StackPanelButtonVerticalAlignmentTopContentSignUpWidth150HorizontalAlignmentRightMargin0,10IsEnabled{BindingPath(dxe:ValidationService。HasValidationError),ElementNamevalidationContainer,Converter{StaticResourceBooleanNegationConverter}}StackPanelGridUserControl MainViewModel。csusingDevExpress。Mvvm;usingDevExpress。Mvvm。DataAnnotations;usingSystem。Windows。Media;namespaceExample。ViewModel{〔POCOViewModel(ImplementIDataErrorInfotrue)〕publicclassMainViewModel:ViewModelBase{staticPropertyMetadataBuilderMainViewModel,stringAddPasswordCheck(PropertyMetadataBuilderMainViewModel,stringbuilder){returnbuilder。MatchesInstanceRule((name,vm)vm。Passwordvm。ConfirmPassword,()Thepasswordsdontmatch。)。MinLength(8,()Thepasswordmustbeatleast8characterslong。)。MaxLength(20,()Thepasswordmustnotexceedthelengthof20。);}publicstaticvoidBuildMetadata(MetadataBuilderMainViewModelbuilder){builder。Property(xx。FirstName)。Required(()Pleaseenterthefirstname。);builder。Property(xx。LastName)。Required(()Pleaseenterthelastname。);builder。Property(xx。Email)。EmailAddressDataType(()Pleaseenteracorrectemailaddress。);AddPasswordCheck(builder。Property(xx。Password))。Required(()Pleaseenterthepassword。);AddPasswordCheck(builder。Property(xx。ConfirmPassword))。Required(()Pleaseconfirmthepassword。);}publicvirtualstringFirstName{get;set;}publicvirtualstringLastName{get;set;}publicvirtualstringEmail{get;set;}publicvirtualstringPassword{get;set;}publicvirtualstringConfirmPassword{get;set;}publicvoidOnPasswordChanged(){this。RaisePropertyChanged(()ConfirmPassword);}publicvoidOnConfirmPasswordChanged(){this。RaisePropertyChanged(()Password);}}} MainViewModel。vbImportsDevExpress。MvvmImportsDevExpress。Mvvm。DataAnnotationsImportsSystem。Windows。MediaNamespaceExample。ViewModelPOCOViewModel(ImplementIDataErrorInfo:True)PublicClassMainViewModelInheritsViewModelBasePrivateSharedFunctionAddPasswordCheck(ByValbuilderAsPropertyMetadataBuilder(OfMainViewModel,String))AsPropertyMetadataBuilder(OfMainViewModel,String)Returnbuilder。MatchesInstanceRule(Function(name,vm)vm。Passwordvm。ConfirmPassword,Function()Thepasswordsdontmatch。)。MinLength(8,Function()Thepasswordmustbeatleast8characterslong。)。MaxLength(20,Function()Thepasswordmustnotexceedthelengthof20。)EndFunctionPublicSharedSubBuildMetadata(ByValbuilderAsMetadataBuilder(OfMainViewModel))builder。Property(Function(x)x。FirstName)。Required(Function()Pleaseenterthefirstname。)builder。Property(Function(x)x。LastName)。Required(Function()Pleaseenterthelastname。)builder。Property(Function(x)x。Email)。EmailAddressDataType(Function()Pleaseenteracorrectemailaddress。)AddPasswordCheck(builder。Property(Function(x)x。Password))。Required(Function()Pleaseenterthepassword。)AddPasswordCheck(builder。Property(Function(x)x。ConfirmPassword))。Required(Function()Pleaseconfirmthepassword。)EndSubPublicOverridablePropertyFirstName()AsStringPublicOverridablePropertyLastName()AsStringPublicOverridablePropertyEmail()AsStringPublicOverridablePropertyPassword()AsStringPublicOverridablePropertyConfirmPassword()AsStringPublicSubOnPasswordChanged()Me。RaisePropertyChanged(Function()ConfirmPassword)EndSubPublicSubOnConfirmPasswordChanged()Me。RaisePropertyChanged(Function()Password)EndSubEndClassEndNamespace DevExpressWPF DevExpressWPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。无论是Office办公软件的衍伸产品,还是以数据为中心的商业智能产品,都能通过DevExpressWPF控件来实现。