按钮绑定到验证

时间:2015-08-07 15:41:14

标签: wpf validation binding

所以我有一个' 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,但只要一个对象有效,它就会启用该按钮。我想赞美这一行动。只要一个对象无效,该按钮就会被禁用。

2 个答案:

答案 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