2011-01-01 4 views
5

안녕 내 응용 프로그램에서 일부 텍스트 상자의 유효성을 검사해야합니다. 나는 유효성 검사 규칙 "DataErrorValidationRule"을 사용하기로 결정했다. 그래서 제 수업에서 IDataErrorInfo 인터페이스를 구현하고 적절한 기능을 작성했습니다. 내 XAML 코드에서 나는 텍스트 상자에 바인딩과 유효성 검사 규칙을 추가 한이 텍스트 상자의wpf - validation - 툴팁을 표시하고 "실행"버튼을 비활성화하는 방법

<TextBox x:Name="txtName" Grid.Column="3" Grid.Row="1" TextAlignment="Center" > 
         <TextBox.Text> 
          <Binding Path="Name" > 
           <Binding.ValidationRules> 
            <DataErrorValidationRule></DataErrorValidationRule> 
           </Binding.ValidationRules> 
          </Binding> 
         </TextBox.Text> 
        </TextBox> 

검증은 OK입니다 - 나는 데이터가 잘못되면 빨간색 프레임이 텍스트 상자에 나타납니다 의미한다. 그러나 내가해야 할 일은 해당 텍스트 상자에 툴팁을 표시하는 것이지만 더 중요한 것은 텍스트 상자에 잘못된 데이터가있는 경우 "실행"버튼을 비활성화해야한다는 것입니다. taht를하는 가장 좋은 방법은 무엇입니까 ??

EDIT 첫 번째 문제는 해결되었지만 나는 다른 문제가 있습니다. 내 단추의 유효성을 검사하려면 MultiBindings를 사용해야합니다. 그

public class Converters : IMultiValueConverter 
{ 

    #region IMultiValueConverter Members 

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if(values !=null && values.Length > 0) 
     { 


      if (values.Cast<type>().Count(val => val) > 0) 
       return false; 
      return true; 
     } 
     return false; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return null; 
    } 

    #endregion 
} 

그러나 나는이 변환기에서 InvalidCastException이 얻을처럼 그

<Button x:Name="btnArrange" Grid.Column="0" Content="Rozmieść" Click="btnArrange_Click" > 
       <Button.Style> 
        <Style TargetType="Button"> 
         <Style.Triggers> 
          <DataTrigger Value="False"> 
           <DataTrigger.Binding> 
            <MultiBinding Converter="{StaticResource BindingConverter}"> 
             <Binding ElementName="txtName" Path="Validation.HasError" /> 
             <Binding ElementName="txtSurname" Path="Validation.HasError"/> 
             <Binding ElementName="txtAddress" Path="Validation.HasError"/> 

            </MultiBinding> 
           </DataTrigger.Binding> 
           <Setter Property="IsEnabled" Value="False"/> 

          </DataTrigger> 
         </Style.Triggers> 
        </Style>   
       </Button.Style> 

     </Button> 

내 변환기 같은 내가 한 STH 보인다. 이 경우 적절한 캐스트는 무엇입니까? HasError가 bool 유형 인 것처럼 thoght하므로 bool로 캐스팅해야합니다.

+0

"유형"이란 무엇을 의미합니까? "if (values.Cast () .Any (val => val))"로 바꾸십시오. " – vorrtex

답변

2

유효성 검사 요약을 만들면 "실행"버튼의 IsEnabled 속성을 HasErrors 속성에 바인딩 할 수 있습니다.

HasErrors이 거짓 일 때 IsEnabledtrue이 되려면 중간 속성 또는 변환기를 사용해야하며 그 반대의 경우도 마찬가지입니다.

+1

유효성 검사 요약을 어떻게 작성합니까? – stylus

+0

@validator - 여기에 하나 있습니다 - http://codeblitz.wordpress.com/2009/05/12/wpf-validation-summary-control/ - 실버 라이트와 혼란스러워졌습니다. 미안합니다. – ChrisF

6
<Window.Resources> 
    <Style x:Key="ElementInError" TargetType="{x:Type FrameworkElement}"> 
     <Style.Triggers> 
      <Trigger Property="Validation.HasError" Value="True"> 
       <Setter Property="ToolTip" 
        Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={x:Static RelativeSource.Self}}"/> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<!-- ... --> 
<TextBox x:Name="txtName" Style="{StaticResource ElementInError}"> 
    <!-- ... -->   
</TextBox> 
<!-- ... --> 
     <Button x:Name="OkButton" Content="Ok" Margin="5" Click="OkButton_Click"> 
      <Button.Style> 
       <Style TargetType="Button"> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding ElementName=txtName,Path=(Validation.HasError)}" Value="True"> 
          <Setter Property="IsEnabled" Value="False" /> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </Button.Style> 
     </Button> 
+0

답변 주셔서 감사합니다. 내 질문에 다시 한 번 응해 주시겠습니까? 편집했습니다. – stylus

17

넣어 도구 설명에 오류 메시지를 표시하려면 당신에 Application.Resources에이 :

<Style x:Key="textBoxInError" TargetType="{x:Type TextBox}"> 
    <Style.Triggers> 
    <Trigger Property="Validation.HasError" Value="true"> 
     <Setter Property="ToolTip" 
     Value="{Binding RelativeSource={x:Static RelativeSource.Self}, 
         Path=(Validation.Errors)[0].ErrorContent}"/> 
    </Trigger> 
    </Style.Triggers> 
</Style> 

(http://msdn.microsoft.com/en-us/library/system.windows.controls.validation.errortemplate.aspx에서 예)

활성화/당신이 뭔가를 사용할 수있는 버튼을 사용하지 않으려면

<Button x:Name="btnOK" Content="OK" IsDefault="True" Click="btnOK_Click"> 
    <Button.Style> 
    <Style TargetType="{x:Type Button}"> 
     <Setter Property="IsEnabled" Value="false" /> 
     <Style.Triggers> 
     <MultiDataTrigger> 
      <MultiDataTrigger.Conditions> 
      <Condition Binding="{Binding ElementName=txt1, Path=(Validation.HasError)}" Value="false" /> 
      <Condition Binding="{Binding ElementName=txt2, Path=(Validation.HasError)}" Value="false" /> 
      </MultiDataTrigger.Conditions> 
      <Setter Property="IsEnabled" Value="true" /> 
     </MultiDataTrigger> 
     </Style.Triggers> 
    </Style> 
    </Button.Style> 
</Button> 

또는 ICommand를 구현하고 comm을 사용할 수 있습니다. 및 바인딩.

편집 여기

은 완전히 동작하는 예제입니다. 두 개의 TextBox가있는 창을 표시합니다. 두 텍스트 상자가 비어 있지 않으면 버튼이 활성화됩니다. ValidationDemo라는 프로젝트를 만들고 그 안에 다음과 같은 파일을 넣어 :

MainWindow.xaml :

<Window x:Class="ValidationDemo.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="146" Width="223"> 
    <Window.Resources> 
    <Style TargetType="{x:Type TextBox}"> 
     <Style.Triggers> 
     <Trigger Property="Validation.HasError" Value="true"> 
      <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/> 
     </Trigger> 
     </Style.Triggers> 
    </Style> 
    </Window.Resources> 
    <Grid> 
    <Label Content="A" Height="28" HorizontalAlignment="Left" Margin="46,7,0,0" Name="label1" VerticalAlignment="Top" /> 
    <TextBox Name="txtA" Text="{Binding Path=TextA, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Height="23" HorizontalAlignment="Left" Margin="69,12,0,0" VerticalAlignment="Top" Width="120" /> 
    <Label Content="B" Height="28" HorizontalAlignment="Left" Margin="46,39,0,0" Name="label2" VerticalAlignment="Top" /> 
    <TextBox Name="txtB" Text="{Binding Path=TextB, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Height="23" HorizontalAlignment="Left" Margin="69,41,0,0" VerticalAlignment="Top" Width="120" /> 
    <Button Name="btnOk" Content="OK" Height="23" HorizontalAlignment="Left" Margin="114,70,0,0" VerticalAlignment="Top" Width="75" Click="btnOk_Click"> 
     <Button.Style> 
     <Style TargetType="{x:Type Button}"> 
      <Setter Property="IsEnabled" Value="false" /> 
      <Style.Triggers> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
       <Condition Binding="{Binding ElementName=txtA, Path=(Validation.HasError)}" Value="false" /> 
       <Condition Binding="{Binding ElementName=txtB, Path=(Validation.HasError)}" Value="false" /> 
       </MultiDataTrigger.Conditions> 
       <Setter Property="IsEnabled" Value="true" /> 
      </MultiDataTrigger> 
      </Style.Triggers> 
     </Style> 
     </Button.Style> 
    </Button> 
    </Grid> 
</Window> 

MainWindow.xaml.cs를 :

using System.Windows; 

namespace ValidationDemo 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 

    private Model model = new Model(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = this.model; 
    } 

    private void btnOk_Click(object sender, RoutedEventArgs e) 
    { 
     Application.Current.Shutdown(); 
    } 
    } 
} 

모델.cs :

using System; 
using System.ComponentModel; 

namespace ValidationDemo 
{ 
    public class Model : INotifyPropertyChanged, IDataErrorInfo 
    { 
    public event PropertyChangedEventHandler PropertyChanged; 

    private string textA = string.Empty; 
    public string TextA 
    { 
     get 
     { 
     return this.textA; 
     } 
     set 
     { 
     if (this.textA != value) 
     { 
      this.textA = value; 
      this.OnPropertyChanged("TextA"); 
     } 
     } 
    } 

    private string textB = string.Empty; 
    public string TextB 
    { 
     get 
     { 
     return this.textB; 
     } 
     set 
     { 
     if (this.textB != value) 
     { 
      this.textB = value; 
      this.OnPropertyChanged("TextB"); 
     } 
     } 
    } 

    public string Error 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public string this[string columnName] 
    { 
     get 
     { 
     string result = string.Empty; 
     switch (columnName) 
     { 
      case "TextA": 
      if (string.IsNullOrEmpty(this.textA)) 
      { 
       result = "'A' must not be empty"; 
      } 
      break; 
      case "TextB": 
      if (string.IsNullOrEmpty(this.textA)) 
      { 
       result = "'B' must not be empty"; 
      } 
      break; 
     } 
     return result; 
     } 
    } 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     if (this.PropertyChanged != null) 
     { 
     this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    } 

} 
+0

불행히도 작동하지 않습니다. 내 텍스트 상자 유효성 검사 중 하나가 실패 했음에도 불구하고 Ok 버튼이 여전히 활성화되어 있음에도 불구하고 – stylus

+0

@validator : 실제 예제를 추가했습니다. – TomBot

관련 문제