C# WPF的现代UI-ModernDialog:仅在某些条件下允许单击“确定”
我启动了一个新的小项目,将ModernUI用于WPF 我必须显示一个只有两个文本框和两个按钮的对话框(确定/取消) 这两个文本框有一些验证(一个是名称,应该大于0,另一个应该是电子邮件) 目前我有以下几点:C# WPF的现代UI-ModernDialog:仅在某些条件下允许单击“确定”,c#,wpf,validation,modern-ui,C#,Wpf,Validation,Modern Ui,我启动了一个新的小项目,将ModernUI用于WPF 我必须显示一个只有两个文本框和两个按钮的对话框(确定/取消) 这两个文本框有一些验证(一个是名称,应该大于0,另一个应该是电子邮件) 目前我有以下几点: var userEditionForm = new UserEditionForm(oneUserConfigurationViewModel); var dlg = new ModernDialog { Title =
var userEditionForm = new UserEditionForm(oneUserConfigurationViewModel);
var dlg = new ModernDialog
{
Title = "User edition",
Content = userEditionForm,
Width = 300
};
dlg.Buttons = new[] {dlg.OkButton, dlg.CancelButton};
dlg.ShowDialog();
return dlg.DialogResult.HasValue && dlg.DialogResult.Value;
内容用户控件是:
<UserControl x:Class="Test.UserControls.UserEditionForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Horizontal" />
<Setter Property="Margin" Value="0,0,0,4" />
</Style>
<Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
<Setter Property="Width" Value="100" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</StackPanel.Resources>
<StackPanel>
<Label Content="Name" Target="{Binding ElementName=TextFirstName}" />
<TextBox x:Name="TextFirstName" Width="150"
Text="{Binding User.Name, RelativeSource={RelativeSource AncestorType=UserControl}, Mode=TwoWay, ValidatesOnDataErrors=True}" />
</StackPanel>
<StackPanel>
<Label Content="Email" Target="{Binding ElementName=TextEmail}" />
<TextBox x:Name="TextEmail" Width="150"
Text="{Binding User.Email, RelativeSource={RelativeSource AncestorType=UserControl}, Mode=TwoWay, ValidatesOnDataErrors=True}" />
</StackPanel>
</StackPanel>
</Grid>
</UserControl>
已经进行了验证,但我想阻止用户单击“确定”,直到验证完成。可能吗?如果是,怎么做?这实际上很棘手,但对我来说很有效: 视图模型
public class UserInfo : INotifyPropertyChanged, IDataErrorInfo
{
private static Regex emailRegex = new Regex(@"^\w+(?:\.\w+)*?@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$");
private string firstname;
private string email;
public string FirstName
{
get { return firstname; }
set { firstname = value; OnPropertyChanged(); }
}
public string EMail
{
get { return email; }
set { email = value; OnPropertyChanged(); }
}
public string Error
{
get { return null; }
}
public string this[string columnName]
{
get
{
switch (columnName)
{
case "FirstName":
return string.IsNullOrWhiteSpace(FirstName) ? "Firstname is required!" : null;
case "EMail":
return EMail == null || !emailRegex.IsMatch(EMail) ? "The Email Address is not valid!" : null;
default:
return null;
}
}
}
public LoginCommand LoginCommand { get; private set; }
public UserInfo()
{
LoginCommand = new LoginCommand(this);
}
private void OnPropertyChanged([CallerMemberName]string propertyName = "")
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
命令(不知道您想叫它什么…)
与ModernUI一起使用
UserInfo info = new UserInfo();
UserInfoForm form = new UserInfoForm(info);
ModernDialog dialog = new ModernDialog
{
Title = "User edition",
Content = form,
Width = 300
};
Button btnOk = dialog.OkButton;
ICommand originalCommand = btnOk.Command; //the original command should close the window so i keep it
btnOk.Command = info.LoginCommand;
info.LoginCommand.AttachCommand(originalCommand); //and attach it to my command
dialog.Buttons = new[] { btnOk, dialog.CancelButton };
dialog.ShowDialog();
不确定现代UI,但通常使用ICommand接口定义命令。。。此命令有一个CanExecute方法,该方法返回bool。。。Execute方法可以设置dialogresult。。。当用户输入数据(INotifyPropertyChanged)引用时,CanExecuteChanged可能会触发:作为旁注:您不必使命令成为viewmodel的成员,但这是常见的做法,自定义命令就像是原始命令的装饰器,我很确定您可以重构它,使其更具可读性,但它可以达到目的。更简单的方法是将您自己的按钮放在用户控件上,并将按钮绑定到命令,因为这是常见的mvvm实践。这非常好,我喜欢。我只是想理解
CanExecute
背后的逻辑:为什么只需要检查这些值是否为空?因为如果它们不为null,就意味着它们通过了验证?非常感谢您的时间:)我喜欢这种很好的方法(冗长,但很好)
UserInfo info = new UserInfo();
UserInfoForm form = new UserInfoForm(info);
ModernDialog dialog = new ModernDialog
{
Title = "User edition",
Content = form,
Width = 300
};
Button btnOk = dialog.OkButton;
ICommand originalCommand = btnOk.Command; //the original command should close the window so i keep it
btnOk.Command = info.LoginCommand;
info.LoginCommand.AttachCommand(originalCommand); //and attach it to my command
dialog.Buttons = new[] { btnOk, dialog.CancelButton };
dialog.ShowDialog();