2015-08-07 2 views
0

Итак, у меня есть кнопка «Сохранить», которую я хочу отключить, если есть ошибки проверки и разрешить, если ошибки не исчезли. У меня есть 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> 

UPDATE: Вот сторона 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

Каков объект, который имеет группа привязки в своем «DataContext»? – OmegaMan

+0

@OmegaMan - это StackPanel наверху. Контакт данных добавляется непосредственно в RadWindow. – cmircovich

ответ

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")); 
       ... 
     } 
... 
... 

Позвольте мне знать, если у вас есть какие-либо сомнения

+0

Я не могу найти место, где я поставил IsValid. – cmircovich

+0

Добавьте его в класс, который обладает остальными свойствами. (т. е. Title, FirstName и т. д.) –

+0

Он не распознает Validation.Errors – cmircovich

0

связывает IsEnabled с BindingGroup Validation.HasError (но с булевым обратным).

Связующие группы были разработаны больше для Отправить/тянуть мотив, где кнопка всегда активна и начинается процесс проверки. Сбой будет устанавливать свойство NotifyOnValidationError на true, но это после факта и не помогает в этой ситуации.

Что вы ищете: push тип проверки, где все проверки могут вносить любые изменения в реальном времени в переменную, к которой может быть привязана кнопка IsEnabled. В качестве примера можно привести Validation in Windows Presentation Foundation - CodeProject.

+0

Я не вижу, где происходит толкание в документации. – cmircovich

Смежные вопросы