DevExpress Universal Subscription
DevExpress WinForms Subscription
DevExpress WPF Subscription
DevExtreme跨平台开发框架
DevExpress VCL Controls
.NET开发框架eXpressApp Framework(XAF)
DevExpress学院
中文文档库
public class LoginViewModel {
public IMessageBoxService MessageBoxService { get { return this.GetService<IMessageBoxService>(); } }
public class DISource : MarkupExtension {
public static Func<Type, object, string, object> Resolver { get; set; }
public Type Type { get; set; }
public object Key { get; set; }
public string Name { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider) => Resolver?.Invoke(Type, Key, Name);
protected override void OnStartup(StartupEventArgs e) {
base.OnStartup(e);
DISource.Resolver = Resolve;
object Resolve(Type type, object key, string name) {
if(type == null)
return null;
if(key != null)
return Container.ResolveKeyed(key, type);
if(name != null)
return Container.ResolveNamed(name, type);
return Container.Resolve(type);
//Attribute-based approach
[POCOViewModel(ImplementIDataErrorInfo = true)]
public class LoginViewModel {
[Required(ErrorMessage = "Please enter the user name.")]
public virtual string UserName { get; set; }
//Fluent API
[POCOViewModel(ImplementIDataErrorInfo = true)]
[MetadataType(typeof(LoginViewModel.Metadata))]
public class LoginViewModel {
public class Metadata : IMetadataProvider<LoginViewModel> {
void IMetadataProvider<LoginViewModel>.BuildMetadata(MetadataBuilder<LoginViewModel> builder) {
builder.Property(x => x.UserName).
Required(() => "Please enter the user name.");
public virtual string UserName { get; set; }
string IDataErrorInfo.this[string columnName] {
get { return IDataErrorInfoHelper.GetErrorText(this, columnName); }
<UserControl x:Class="Example.View.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModel="clr-namespace:Example.ViewModel"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="400"
DataContext="{dxmvvm:ViewModelSource Type=ViewModel:MainViewModel}">
<UserControl.Resources>
<dxmvvm:BooleanNegationConverter x:Key="BooleanNegationConverter"/>
</UserControl.Resources>
<StackPanel Orientation="Vertical" Margin="10" dxe:ValidationService.IsValidationContainer="True" x:Name="validationContainer">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" Margin="0,0,4,6">
<TextBlock Text="Name" Margin="6,2,0,2"/>
<dxe:TextEdit NullText="First" EditValue="{Binding FirstName, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="4,0,0,6" Grid.Column="1">
<TextBlock Text=" " Margin="6,2,0,2"/>
<dxe:TextEdit NullText="Last" EditValue="{Binding LastName, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Grid>
<StackPanel Orientation="Vertical" Margin="0,0,0,6">
<TextBlock Text="Email" Margin="6,2,0,2"/>
<dxe:TextEdit EditValue="{Binding Email, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="0,0,0,6">
<TextBlock Text="Password" Margin="6,2,0,2"/>
<dxe:PasswordBoxEdit EditValue="{Binding Password, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="0,0,0,6">
<TextBlock Text="Confirm Password" Margin="6,2,0,2"/>
<dxe:PasswordBoxEdit EditValue="{Binding ConfirmPassword, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<Button VerticalAlignment="Top" Content="Sign Up" Width="150" HorizontalAlignment="Right" Margin="0,10"
IsEnabled="{Binding Path=(dxe:ValidationService.HasValidationError), ElementName=validationContainer, Converter={StaticResource BooleanNegationConverter}}"/>
</StackPanel>
</Grid>
</UserControl>
namespace Example.ViewModel {
[POCOViewModel(ImplementIDataErrorInfo = true)]
public class MainViewModel : ViewModelBase {
static PropertyMetadataBuilder<MainViewModel, string> AddPasswordCheck(PropertyMetadataBuilder<MainViewModel, string> builder) {
return builder.MatchesInstanceRule((name, vm) => vm.Password == vm.ConfirmPassword, () => "The passwords don't match.")
.MinLength(8, () => "The password must be at least 8 characters long.")
.MaxLength(20, () => "The password must not exceed the length of 20.");
public static void BuildMetadata(MetadataBuilder<MainViewModel> builder) {
builder.Property(x => x.FirstName)
.Required(() => "Please enter the first name.");
builder.Property(x => x.LastName)
.Required(() => "Please enter the last name.");
builder.Property(x => x.Email)
.EmailAddressDataType(() => "Please enter a correct email address.");
AddPasswordCheck(builder.Property(x => x.Password))
.Required(() => "Please enter the password.");
AddPasswordCheck(builder.Property(x => x.ConfirmPassword))
.Required(() => "Please confirm the password.");
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string Email { get; set; }
public virtual string Password { get; set; }
public virtual string ConfirmPassword { get; set; }
public void OnPasswordChanged() {
this.RaisePropertyChanged(() => ConfirmPassword);
public void OnConfirmPasswordChanged() {
this.RaisePropertyChanged(() => Password);
Imports DevExpress.Mvvm
Imports DevExpress.Mvvm.DataAnnotations
Imports System.Windows.Media
Namespace Example.ViewModel
<POCOViewModel(ImplementIDataErrorInfo := True)> _
Public Class MainViewModel
Inherits ViewModelBase
Private Shared Function AddPasswordCheck(ByVal builder As PropertyMetadataBuilder(Of MainViewModel, String)) As PropertyMetadataBuilder(Of MainViewModel, String)
Return builder.MatchesInstanceRule(Function(name, vm) vm.Password = vm.ConfirmPassword, Function() "The passwords don't match.").MinLength(8, Function() "The password must be at least 8 characters long.").MaxLength(20, Function() "The password must not exceed the length of 20.")
End Function
Public Shared Sub BuildMetadata(ByVal builder As MetadataBuilder(Of MainViewModel))
builder.Property(Function(x) x.FirstName).Required(Function() "Please enter the first name.")
builder.Property(Function(x) x.LastName).Required(Function() "Please enter the last name.")
builder.Property(Function(x) x.Email).EmailAddressDataType(Function() "Please enter a correct email address.")
AddPasswordCheck(builder.Property(Function(x) x.Password)).Required(Function() "Please enter the password.")
AddPasswordCheck(builder.Property(Function(x) x.ConfirmPassword)).Required(Function() "Please confirm the password.")
End Sub
Public Overridable Property FirstName() As String
Public Overridable Property LastName() As String
Public Overridable Property Email() As String
Public Overridable Property Password() As String
Public Overridable Property ConfirmPassword() As String
Public Sub OnPasswordChanged()
Me.RaisePropertyChanged(Function() ConfirmPassword)
End Sub
Public Sub OnConfirmPasswordChanged()
Me.RaisePropertyChanged(Function() Password)
End Sub
End Class
End Namespace
本站文章除注明转载外,均为本站原创或翻译
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果
转载请注明:文章转载自:DevExpress控件中文网 [https://www.devexpresscn.com/]
本文地址:https://www.devexpresscn.com/post/3041.html
相关产品:
DevExpress Universal Subscription,