2011-06-28 44 views
13

我有几个文本框与自定义验证程序:
(我不介意如果“错误”的数据发送回对象(属性是字符串),我只需要防止功能如果有错误,所以如果绑定是不是那种验证请告诉正确的位置的按钮。我就像Validation.ErrorTemplate支持,我可以使用)禁用按钮验证错误

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

我怎样才能禁用特定如果出现任何验证错误,按钮?

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

这里可能重复:http://stackoverflow.com/questions/231052/using-wpf-validation-rules-and-disabling-a-save - 按钮 – Damascus

+1

在那里的帖子不回答问题... – anderi

回答

34

您可以在ButtonStyle.Triggers使用MultiDataTrigger属性。假设我们有一个名为“txtName”的TextBox。我们必须禁用验证错误TextBox上的按钮“btnSave”。

这里是你可以做什么:

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

希望这会帮助你。

+7

如果其他人不知道我没有这样做,那么你必须在'Validation.HasError'路径上有括号。 [这就是它的附加属性。](http://stackoverflow.com/a/14382796/1229237)没有它们,你会得到一个'System.Windows.Data警告:40:BindingExpression路径错误'就像我一样了。 –

+0

@ S.Mishra如果我有两个文本框? 编辑:NVM。只需添加几乎相同的行条件绑定。 –

+0

@p__d我相信你可以在部分添加更多。每个输入控件都有。 –

3

CanExecute在MVVM中是用于授权管理的,但人们使用它进行验证。最好的方法是在XAML中完成。如果您有多个字段进行验证,您将需要一个转换器(InverseAndBooleansToBooleanConverter是我的多个布尔值的实现)。这里是如何做到这一点:

XAML代码(对不起,如果在XAML代码确实显示,因为我可以让它出现,即使我尝试过):

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

转换器

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

添加到您的TextBlock:

Validation.Error="Save_Error" 

代码隐藏(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; 

    } 
}