2011-06-28 33 views
13

Tôi có vài hộp văn bản có trình xác thực tùy chỉnh:
(Tôi không ngại nếu dữ liệu "sai" được gửi trở lại đối tượng (thuộc tính là chuỗi), tôi chỉ cần ngăn chặn chức năng của một nút nếu có một lỗi, vì vậy nếu các ràng buộc không phải là nơi thích hợp cho rằng loại xác nhận xin vui lòng cho. tôi giống như sự ủng hộ Validation.ErrorTemplate mà tôi có thể sử dụng)Nút tắt trên Lỗi xác thực

<ControlTemplate x:Key="validator" > 
    <DockPanel LastChildFill="True"> 
     <TextBlock DockPanel.Dock="Right" Foreground="Red" FontSize="12pt">!</TextBlock> 
     <Border BorderBrush="Red" BorderThickness="1.0"> 
      <AdornedElementPlaceholder /> 
     </Border> 
    </DockPanel> 
</ControlTemplate> 

<TextBox Height="23" Width="150" TextWrapping="Wrap" 
     Validation.ErrorTemplate="{StaticResource validator}"> 
     <TextBox.Text> 
      <Binding Path="StringProperty" UpdateSourceTrigger="LostFocus"> 
       <Binding.ValidationRules> 
        <local:NumbersOnly/> 
       </Binding.ValidationRules> 
      </Binding> 
     </TextBox.Text> 
</TextBox> 

Làm thế nào tôi có thể vô hiệu hóa cụ thể nút nào nếu lỗi xác thực được nâng lên?

<Button Content="DO Work" Height="57" HorizontalAlignment="Left" Name="button1" VerticalAlignment="Top" Width="234" Click="button1_Click" /> 
+0

có thể trùng lặp ở đây: http://stackoverflow.com/questions/231052/using-wpf-validation-rules-and-disabling-a-save -button – Damascus

+1

các bài đăng ở đó không trả lời câu hỏi ... – anderi

Trả lời

34

Bạn có thể sử dụng bất động sản trong MultiDataTriggerStyle.Triggers của Button. Giả sử rằng chúng tôi có một tên là "txtName" TextBox. Chúng tôi phải tắt nút "btnSave" trên lỗi xác thực của TextBox.

Dưới đây là những gì bạn có thể làm:

<Button Content="Save" 
     Grid.Column="1" 
     Grid.Row="3" 
     HorizontalAlignment="Right" 
     Height="23" 
     Name="btnSave" 
     Width="75" 
     IsDefault="True" 
     Command="{Binding SaveProtocolCommand}" 
     Margin="3"> 
    <Button.Style> 
    <Style TargetType="Button"> 
     <Setter Property="IsEnabled" Value="False"/> 
     <Style.Triggers> 
     <MultiDataTrigger> 
      <MultiDataTrigger.Conditions> 
      <Condition Binding="{Binding Path=(Validation.HasError), ElementName=txtName}" Value="False"/> 
      </MultiDataTrigger.Conditions> 
      <Setter Property="IsEnabled" Value="True"/> 
     </MultiDataTrigger> 
     </Style.Triggers> 
    </Style> 
    </Button.Style> 
</Button> 

Hy vọng điều này sẽ giúp bạn.

+7

Trong trường hợp người khác không biết điều này như tôi đã không, bạn phải có các dấu ngoặc đơn xung quanh đường dẫn 'Validation.HasError'. [Đó là cách nó đề cập đến thuộc tính đính kèm.] (Http://stackoverflow.com/a/14382796/1229237) Nếu không có chúng, bạn sẽ nhận được một 'System.Windows.Data Cảnh báo: 40: Lỗi đường dẫn BindingExpression' giống như tôi đã có. –

+0

@ S.Mishra nếu tôi có hai hộp văn bản thì sao? Chỉnh sửa: NVM. Chỉ cần thêm gần như giống như điều kiện ràng buộc dòng. –

+0

@p__d Tôi tin rằng bạn có thể thêm nhiều hơn trong phần . Mỗi cho mọi điều khiển đầu vào. –

0

Nếu bạn sử dụng MVVM thì chỉ cần triển khai phương thức CanExecute của giao diện ICommand. Button doesn't become disabled when command CanExecute is false

Nếu bạn viết logic của bạn trong codebehind sau đó chỉ cần sử dụng một tài sản của một nút IsEnabled:

XAML:

<Button Name=_btn/> 

SomeForm.xaml.cs:

_btn.IsEnabled=false; 
3

CanExecute trong MVVM là dành cho quản lý ủy quyền nhưng mọi người sử dụng nó để xác thực. Cách tốt nhất là làm điều đó trong XAML. Bạn sẽ cần một bộ chuyển đổi nếu bạn có nhiều trường để xác thực (InverseAndBooleansToBooleanConverter là việc triển khai của tôi cho nhiều giá trị Booleans). Dưới đây là làm thế nào để làm như vậy:

mã XAML (Tôi xin lỗi nếu mã XAML không hiển thị bởi vì tôi có thể có nó xuất hiện ngay cả khi tôi đã cố gắng):

<Button Name="Button_Test" Content="Test"> 
    <Button.IsEnabled> 
     <MultiBinding Converter="{StaticResource InverseAndBooleansToBooleanConverter}" Mode="TwoWay"> 
      <Binding ElementName="TextBox_Field1" Path="(Validation.HasError)" /> 
      <Binding ElementName="TextBox_Field2" Path="(Validation.HasError)" /> 
      <Binding ElementName="TextBox_Field3" Path="(Validation.HasError)" /> 
     </MultiBinding> 
    </Button.IsEnabled> 
</Button> 

Bộ chuyển đổi

public class InverseAndBooleansToBooleanConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (values.LongLength > 0) 
     { 
      foreach (var value in values) 
      { 
       if (value is bool && (bool)value) 
       { 
        return false; 
       } 
      } 
     }  
     return true; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
      throw new NotImplementedException(); 
    } 
} 
1

Thêm phần này vào TextBlock của bạn:

Validation.Error="Save_Error" 

CodeBehind (xaml.cs):

public partial class MyView : Window 
{ 
    private int _noOfErrorsOnScreen = 0; 

    public MyView() 
    { 
     InitializeComponent(); 
    } 


    private void Save_Error(object sender, ValidationErrorEventArgs e) 
    { 
     if (e.Action == ValidationErrorEventAction.Added) 
      _noOfErrorsOnScreen++; 
     else 
      _noOfErrorsOnScreen--; 

     Save.IsEnabled = _noOfErrorsOnScreen > 0 ? false : true; 

    } 
} 
Các vấn đề liên quan