所以我有一个' Save'如果有任何验证错误我想要禁用的按钮,如果错误消失则启用。我有一个BindingGroup,并想知道我是否可以将IsEnabled绑定到BindingGroup Validation.HasError(但布尔反转)。
以下是我对xaml的设置
<telerik:RadWindow x:Class="Outreach_Application_1.MVVM.ContactPopup"
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"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
Header="Contact Details"
mc:Ignorable="d" Style="{DynamicResource ContactWindowDictionary}">
<StackPanel>
<StackPanel.BindingGroup>
<BindingGroup Name="ContactGroup" />
</StackPanel.BindingGroup>
<Border Width="Auto" Height="25" Background="{StaticResource DhpBlueBrush}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="White" FontWeight="Bold" FontSize="12"
Text="{Binding ContactWindowHeader}"/>
</Border>
<DockPanel>
<StackPanel Margin="4">
<Label Content="Title" FontWeight="Bold" HorizontalContentAlignment="Right"/>
<Label Content="First" FontWeight="Bold" HorizontalContentAlignment="Right"/>
<Label Content="MI" FontWeight="Bold" HorizontalContentAlignment="Right"/>
<Label Content="Last" FontWeight="Bold" HorizontalContentAlignment="Right"/>
<Label Content="Position" FontWeight="Bold" HorizontalContentAlignment="Right"/>
<Label Content="Email" FontWeight="Bold" HorizontalContentAlignment="Right"/>
<Label Content="Phone" FontWeight="Bold" HorizontalContentAlignment="Right"/>
<Label Content="Phone Ext." FontWeight="Bold" HorizontalContentAlignment="Right"/>
<Label Content="Fax" FontWeight="Bold" HorizontalContentAlignment="Right"/>
</StackPanel>
<StackPanel Margin="4" Width="400">
<!-- Title -->
<ComboBox Width="50" Margin="2" HorizontalAlignment="Left"
SelectedValue="{Binding Path=Title,
Mode=TwoWay}"
ItemsSource="{Binding Path=TitleSource,
Mode=TwoWay}" />
<!-- First Name -->
<telerik:RadMaskedTextInput Margin="2" Width="125"
IsClearButtonVisible="False"
Mask=""
SelectionOnFocus="Unchanged"
TextMode="PlainText"
AllowInvalidValues="True"
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}"
Value="{Binding Path=FirstName,
Mode=TwoWay,
ValidatesOnDataErrors=True,
BindingGroupName=ContactGroup,
UpdateSourceTrigger=PropertyChanged}" />
<!-- Middle Initial -->
<telerik:RadMaskedTextInput Margin="2" Width="30"
AllowInvalidValues="True"
IsClearButtonVisible="False"
Mask=""
SelectionOnFocus="Unchanged"
TextMode="PlainText"
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}"
Value="{Binding Path=MiddleInitial,
Mode=TwoWay,
ValidatesOnDataErrors=True,
BindingGroupName=ContactGroup,
UpdateSourceTrigger=PropertyChanged}" />
<!-- Last Name -->
<telerik:RadMaskedTextInput Margin="2" Width="125"
AllowInvalidValues="True"
IsClearButtonVisible="False"
Mask=""
SelectionOnFocus="Unchanged"
TextMode="PlainText"
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}"
Value="{Binding Path=LastName,
Mode=TwoWay,
ValidatesOnDataErrors=True,
BindingGroupName=ContactGroup,
UpdateSourceTrigger=PropertyChanged}" />
<!-- Position -->
<telerik:RadMaskedTextInput Margin="2" Width="125"
IsClearButtonVisible="False"
Mask=""
SelectionOnFocus="Unchanged"
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}"
Value="{Binding Path=Position,
Mode=TwoWay}" />
<!-- Email -->
<telerik:RadMaskedTextInput Margin="2" Width="125"
AllowInvalidValues="True"
IsClearButtonVisible="False"
Mask=""
SelectionOnFocus="Unchanged"
TextMode="PlainText"
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}"
Value="{Binding Path=Email,
Mode=TwoWay,
ValidatesOnDataErrors=True,
BindingGroupName=ContactGroup,
UpdateSourceTrigger=PropertyChanged}" />
<!-- Phone Number -->
<telerik:RadMaskedTextInput Margin="2" Width="100"
AllowInvalidValues="True"
IsClearButtonVisible="False"
Mask="(ddd) ddd-dddd"
SelectionOnFocus="Unchanged"
TextMode="PlainText"
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}"
Value="{Binding Path=PhoneNumber,
Mode=TwoWay,
ValidatesOnDataErrors=True,
BindingGroupName=ContactGroup,
UpdateSourceTrigger=PropertyChanged}" />
<!-- Phone Extension -->
<telerik:RadMaskedTextInput Margin="2" Width="50"
IsClearButtonVisible="False"
Mask=""
SelectionOnFocus="Unchanged"
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}"
Value="{Binding Path=PhoneExtension,
Mode=TwoWay,
ValidatesOnDataErrors=True,
BindingGroupName=ContactGroup,
UpdateSourceTrigger=PropertyChanged}" />
<!-- Fax Number -->
<telerik:RadMaskedTextInput Margin="2" Width="100"
AllowInvalidValues="True"
IsClearButtonVisible="False"
Mask="(ddd) ddd-dddd"
SelectionOnFocus="Unchanged"
TextMode="PlainText"
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}"
Value="{Binding Path=FaxNumber,
Mode=TwoWay,
ValidatesOnDataErrors=True,
BindingGroupName=ContactGroup,
UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DockPanel>
<Border BorderBrush="Black" BorderThickness="0,0,0,1" Margin="0 6" />
<DockPanel HorizontalAlignment="Center">
<Button Content="Cancel" Width="50" FontWeight="Bold" Margin="16 4"
Click="CancelContact_OnClick"/>
<Button Content="Save" Width="50" FontWeight="Bold" Margin="16 4"
Click="SaveContact_OnClick"
IsEnabled="{Binding BindingGroupName=ContactGroup, Path=(Validation.Errors)}">
</Button>
</DockPanel>
</StackPanel>
</telerik:RadWindow>
更新:这是我正在使用的ViewModel方面
public class Contact : ViewModelBase, IDataErrorInfo, INotifyPropertyChanged
{
private string _email;
private string _faxNumber;
private string _firstName;
private string _lastName;
private string _middleInitial;
private string _phoneExtension;
private string _phoneNumber;
private string _position;
private string _error = string.Empty;
//Declare contact variables
private string _title;
private bool _canSave;
//Title
public string Title
{
get { return _title; }
set
{
_title = value;
OnPropertyChanged("Title");
}
}
//First Name
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
//MiddleInitial
public string MiddleInitial
{
get { return _middleInitial; }
set
{
_middleInitial = value;
OnPropertyChanged("MiddleInitial");
}
}
//Last Name
public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
OnPropertyChanged("LastName");
}
}
//Position
public string Position
{
get { return _position; }
set
{
_position = value;
OnPropertyChanged("Position");
}
}
//Email
public string Email
{
get { return _email; }
set
{
_email = value;
OnPropertyChanged("Email");
}
}
//Phone Number
public string PhoneNumber
{
get { return _phoneNumber; }
set
{
_phoneNumber = value;
OnPropertyChanged("PhoneNumber");
}
}
//Phone Extension
public string PhoneExtension
{
get { return _phoneExtension; }
set
{
_phoneExtension = value;
OnPropertyChanged("PhoneExtension");
}
}
//Fax Number
public string FaxNumber
{
get { return _faxNumber; }
set
{
_faxNumber = value;
OnPropertyChanged("FaxNumber");
}
}
public bool CanSave
{
get { return this._canSave; }
set
{
this._canSave = value;
base.OnPropertyChanged("CanSave");
}
}
#region IDataErrorInfo Members
public string Error
{
get { return _error; }
}
public string this[string columnName]
{
get
{
_error = string.Empty;
string pattern;
//First name Validation
pattern = @"\b^[A-Za-z][a-zA-Z '&-]*[A-Za-z]*$\b";
if (columnName == "FirstName" && Regex.IsMatch(FirstName, pattern) == false)
{
_error = "Invalid first name.";
CanSave = false;
}
if (columnName == "FirstName" && string.IsNullOrWhiteSpace(FirstName))
{
_error = "First name is required.";
CanSave = false;
}
//Middle Initial Validation
pattern = @"(^$)|\b^[A-Za-z]$\b";
if (columnName == "MiddleInitial" && Regex.IsMatch(MiddleInitial, pattern) == false)
{
_error = "Invalid middle initial.";
CanSave = false;
}
//Last name validation
pattern = @"\b^[A-Za-z][a-zA-Z '&-]*[A-Za-z]*$\b";
if (columnName == "LastName" && Regex.IsMatch(LastName, pattern) == false)
{
_error = "Invalid last name.";
CanSave = false;
}
if (columnName == "LastName" && string.IsNullOrWhiteSpace(LastName))
{
_error = "Last name is required.";
CanSave = false;
}
//Email validation
pattern =
@"^(?("")("".+?(?<!\\)""@)|(([0-9a-zA-Z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9A-Za-z])@))" +
@"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]*\.)+[A-Za-z0-9][\-A-Za-z0-9]{0,22}[A-Za-z0-9]))$";
if (columnName == "Email" && Regex.IsMatch(Email, pattern) == false)
{
_error = @"Please enter a valid email address.";
CanSave = false;
}
if (columnName == "Email" && string.IsNullOrWhiteSpace(Email))
{
_error = @"Email address is required.";
CanSave = false;
}
//Phone number validation
pattern = @"^[0-9]{10}$";
if (columnName == "PhoneNumber" && Regex.IsMatch(PhoneNumber, pattern) == false)
{
_error = "Please enter a 10 digit phone number.";
CanSave = false;
}
if (columnName == "PhoneNumber" && string.IsNullOrWhiteSpace(PhoneNumber))
{
_error = "A phone number is required.";
CanSave = false;
}
//Phone extension validation
pattern = @"^(^$)|[0-9]+$";
if (columnName == "PhoneExtension" && Regex.IsMatch(PhoneExtension, pattern) == false)
{
_error = "Only numerical digits are allowed.";
CanSave = false;
}
//Fax number validation
pattern = @"^[0-9]{10}$";
if (columnName == "FaxNumber" && Regex.IsMatch(FaxNumber, pattern) == false)
{
_error = "Please enter a 10 digit fax number.";
CanSave = false;
}
if (columnName == "FaxNumber" && string.IsNullOrWhiteSpace(FaxNumber))
{
_error = "A fax number is required.";
CanSave = false;
}
return _error;
}
}
#endregion
}
我尝试将保存按钮绑定到CanSave,但只要一个对象有效,它就会启用该按钮。我想赞美这一行动。只要一个对象无效,该按钮就会被禁用。
答案 0 :(得分:0)
实际上非常简单,
<强> XAML 强>
<Button Content="Save" Width="50" FontWeight="Bold" Margin="16 4"
Click="SaveContact_OnClick"
IsEnabled="{Binding Path=IsValid}">
Model.cs
...
...
//Below Code to check if the model is Valid (without errors)
public bool IsValid
{
get
{
return (Validation.Errors.Count == 0);
}
}
//Also you might need to add the below line in your property changed
protected virtual void OnPropertyChanged(string propertyName)
{
...
//Below line is needed to fire Notify Property changed
this.PropertyChanged(this, new PropertyChangedEventArgs("IsValid"));
...
}
...
...
如果您有任何疑问,请告诉我
答案 1 :(得分:0)
将IsEnabled绑定到BindingGroup Validation.HasError(但布尔反转)。
绑定组的设计更多是针对提交 / pull 主题,其中按钮始终处于活动状态并启动验证过程。失败会将NotifyOnValidationError 属性设置为true
,但这是在事实之后,并且在这种情况下没有帮助。
您所寻求的是推送类型验证,其中所有验证都可以将任何实时更改推送到变量,该变量可以由按钮的IsEnabled
绑定。
有关示例,请参阅Validation in Windows Presentation Foundation - CodeProject。