2016-10-06 8 views
-1

私は複数のビュー(A、B、Cなど)と対応するビューモデルを持つC#/ WPFアプリケーションを開発しています。将来的にはアプリでうまくいく。 各ビューには、テキストボックス、コンボボックス、日時ピッカーなどのさまざまなコントロールがあります。WPFアプリケーションの必須フィールドの検証

私は、開発者が新しく追加されたビューのコントロールを検証するための最小限のコードを追加する必要があるように、必須フィールドの検証方法を考え出しています。

私の現在のアプローチ:

すべての私の見解モデルは「ViewModelBase」.I'veと呼ばれる基本クラスから継承するには、このクラスで)IsRequiredFieldValueBlank(と呼ばれる新しいメソッドを追加しました:私は

public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable 
     public bool IsRequiredFieldValueBlank(object inputObject) 
     { 
      bool isRequiredFieldValueBlank = true; 
      try 
      { 
       var arrProperties = inputObject.GetType().GetProperties(); 

       foreach (var prop in arrProperties) 
       { 
        if (!prop.CanWrite) 
         continue; 
        if(prop.PropertyType.Name.ToUpper() == "STRING") 
        {       
         if (string.IsNullOrEmpty(prop.GetValue(inputObject).ToString())) 
         { 
          isRequiredFieldValueBlank = true; 
          break; 
         } 
        } 

       } 

      } 
      catch (Exception ex) 
      { 
       //TBD:Handle exception here 
      } 
      return isRequiredFieldValueBlank; 
     } 
} 

<TextBox HorizontalAlignment="Left" Height="23" VerticalAlignment="Top" Width="180" TabIndex="1" Text="{Binding ProductDescription,NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" Style="{DynamicResource RequiredFieldStyle}" Grid.Row="1" Grid.Column="3" Margin="1,10,0,0" /> 

そして、私のMainWindoResources.xaml

01の中: "A" ビューのXAMLコードは、私は次のコードをしました
<Style TargetType="TextBox" x:Key="RequiredFieldStyle"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding Path=ViewModelBase.IsRequiredFieldValueBlank}" Value="false"> 
       <Setter Property="Background" Value="BurlyWood" /> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding Path=ViewModelBase.IsRequiredFieldValueBlank}" Value="true"> 
       <Setter Property="Background" Value="LightGreen" /> 
       <Setter Property="Foreground" Value="DarkGreen" /> 
      </DataTrigger>    
     </Style.Triggers> 
    </Style> 

App.xaml:

<Application x:Class="MyTool.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      StartupUri="MainWindow.xaml" 
      Startup="Application_Startup"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="Views/MainWindowResources.xaml"/> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 

    </Application.Resources> 
</Application> 

私の質問:? 1.Isこの正しいアプローチはい、私はコードが文句を言わないXAMLはIsRequiredFieldValueBlankにinpoObjectを渡していないため、動作することを理解していれば()メソッドをViewModelBaseクラスに追加します。 誰かがそれを実現する方法についてアドバイスできますか?

2.この問題を処理する他の方法はありますか?

ありがとうございました。

答えて

0

あなたはIDataErrorInfoINotifyPropertyChangedインタフェースとの組み合わせで、検証のためValidator静的クラスを活用する場合は、長期的にはあなたの人生がずっと簡単にすることができます。ここではPRISMのBindableBaseクラスに拡張する非常に基本的な実装です:

public abstract class ViewModelBase : IDataErrorInfo, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public string Error => string.Join(Environment.NewLine, GetValidationErrors()); 

    public bool IsValid => !GetValidationErrors().Any(); 

    public string this[string columnName] => 
     GetValidationErrors().FirstOrDefault(result => result.MemberNames.Contains(columnName))?.ErrorMessage; 

    protected IEnumerable<ValidationResult> GetValidationErrors() 
    { 
     var context = new ValidationContext(this); 
     var results = new List<ValidationResult>(); 

     Validator.TryValidateObject(this, context, results, true); 

     return results; 
    } 

    protected virtual void OnPropertChanged([CallerMemberName]string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName]string propertyName = null) 
    { 
     if (Equals(storage, value)) 
     { 
      return false; 
     } 

     storage = value; 
     OnPropertChanged(propertyName); 
     return true; 
    } 
} 

あなたは本当にだけでなく、その後、RequiredFieldStyleファイルは必要ありません。検証は、次のように行うことができます。

public class ViewModelExample : ViewModelBase 
{ 
    private string _myString; 

    // do validation with annotations and IValidateableObject 
    [Required] 
    [StringLength(50)] 
    public string MyString 
    { 
     get { return _myString; } 
     set { SetProperty(ref _myString, value); } 
    } 
} 

ただ、オブジェクトが保存する前に有効であるかどうかを確認するためにIsValidプロパティを確認してください。

関連する問題