2011-01-27 8 views
1

誰でもINotifyDataErrorInfoインターフェイスを正常に適用し、AutoCompleteBoxにバインドしていますか。私はこれを試したが、私は応答を得ない。コントロールは他のコントロール、つまり赤い枠線と警告ツールチップとして反応しません。また、Validation Summaryコントロールにエラーが表示されることもありません。SilverlightのAutoCompleteBoxとINotifyDataErrorInfo

私は正常に標準のテキストボックスとDatePickersを設定しました。これらは、インターネット上の人々が親切に提供してくれた多くの例に従って完全に動作します。

私の画面の一貫性のためにこれに答えがあったなら、私は単純に保存する準備ができたらボタンを有効にするためにINotifyDataErrorInfoに付属するHasErrorsプロパティにバインドしたいので、これらのボックスが正しいことを確認するために余分なコードを使わずにこれを行います。

現時点では、MVVMLightのEventToCommandバインディングを使用してLostFocusイベントを登録することによって、これらの処理方法が異なります。 ViewModelには

<sdk:AutoCompleteBox x:Name="TransferTypeTextBox" SelectedItem="{Binding Path=SelectedTransferType, Mode=TwoWay, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}" ItemsSource="{Binding Path=TransferTypes}" IsTextCompletionEnabled="True" Grid.Row="1" Grid.Column="1" Margin="0,3" Width="238" HorizontalAlignment="Left" FontFamily="/PtrInput_Silverlight;component/Fonts/Fonts.zip#Calibri" FontSize="13.333"> 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="LostFocus"> 
       <cmd:EventToCommand Command="{Binding TransferTypeLostFocusCommand}" PassEventArgsToCommand="True"/> 
      </i:EventTrigger> 
     </i:Interaction.Triggers> 
</sdk:AutoCompleteBox> 

私は、テキストボックスにRoutedEventArgs.OriginalSourceをキャストし、そのようなテキストを取得し、それが空またはボックスのリスト内の項目に一致しない限りボックスを残してからユーザーを防止: -

private void OnTransferTypeLostFocus(RoutedEventArgs e) 
    { 
     System.Windows.Controls.TextBox box = (System.Windows.Controls.TextBox)e.OriginalSource; 

     // If user inputs text but doesn't select one item, show message. 
     if (this.Ptr.TransferType == null && !string.IsNullOrEmpty(box.Text)) 
     { 
      MessageBox.Show("That is not a valid entry for Transfer Type", "Transfer type", MessageBoxButton.OK); 
      box.Focus(); 
     } 
    } 

答えて

1

できるだけ簡単な例を書いてみました。 私のモデルは、SearchTextプロパティの変更を観察し、検証プロパティを更新します。

public class MainViewModel : INotifyPropertyChanged, INotifyDataErrorInfo 
{ 
    private Dictionary<string, List<string>> ErrorMessages = new Dictionary<string, List<string>>(); 

    public MainViewModel() 
    { 
     //Validation works automatically for all properties that notify about the changes 
     this.PropertyChanged += new PropertyChangedEventHandler(ValidateChangedProperty); 
    } 

    //Validate and call 'OnErrorChanged' for reflecting the changes in UI 
    private void ValidateChangedProperty(object sender, PropertyChangedEventArgs e) 
    { 
     if (e.PropertyName == "HasErrors") //avoid recursion 
      return; 

     this.ValidateProperty(e.PropertyName); 
     OnErrorsChanged(e.PropertyName); 
     OnPropertyChanged("HasErrors"); 
    } 

    //Just compare a received value with a correct value, it's a simple rule for demonstration 
    public void ValidateProperty(string propertyName) 
    { 
     if (propertyName == "SearchText") 
     { 
      this.ErrorMessages.Remove(propertyName); 
      if (SearchText != "Correct value") 
       this.ErrorMessages.Add("SearchText", new List<string> { "Enter a correct value" }); 
     } 

    } 

    private string searchText; 

    public string SearchText 
    { 
     get { return searchText; } 
     set 
     { 
      searchText = value; 
      OnPropertyChanged("SearchText"); 
     } 
    } 



    #region INotifyDataErrorInfo 

    public IEnumerable GetErrors(string propertyName) 
    { 
     return this.ErrorMessages.Where(er => er.Key == propertyName).SelectMany(er => er.Value); 
    } 

    public bool HasErrors 
    { 
     get { return this.ErrorMessages.Count > 0; } 
    } 

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged = delegate { }; 

    private void OnErrorsChanged(string propertyName) 
    { 
     ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); 
    } 
    #endregion 


    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 

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

とXAML:

<sdk:AutoCompleteBox Text="{Binding SearchText, Mode=TwoWay}" /> 
<Button IsEnabled="{Binding HasErrors, Converter={StaticResource NotConverter}}" Content="Save"/> 

制御は、赤い枠があり、モデルにエラーがあると、ボタンは無効になります。

+0

ありがとうございます - 私はこれを試してみます。気にしない場合は、ViewModelからAutoCompleteBoxをクリアすることができるかどうか尋ねたいと思います。私は、SelectedItemとTextへのバインディングを持っていますが、ViewModel(つまりnullとString.Empty)でこれらをクリアすることはできますが、AutoCompleteBoxの元のSearchTextプロパティはそのまま残り、Textをユーザー入力にリセットします。最終的な選択ではなく、ドロップダウンを促した最初に入力された文字)。私はそれを並べ替えることができないので、この質問は多くのフォーラムに掲載されています。 – EzaBlade

+0

プロパティ内でOnPropertyChangedを呼び出し、BindingをTwoWayとして設定してください。私の例はこれらの条件を実装しているので、あなたの問題を解決するはずです。そうでない場合は、問題の詳細な説明で新しい質問をすることができます。 – vorrtex

+0

私は自分の問題を解決しました。 – EzaBlade

関連する問題