2011-01-27 3 views
1

Кто-нибудь успешно применил интерфейс INotifyDataErrorInfo и привязан к AutoCompleteBox. Я пробовал это, но я не получил ответа. Элемент управления не отвечает, как другие элементы управления, т. Е. С красной рамкой и всплывающей подсказкой. Он также не отображает отображение сводной информации с его ошибкой.AutoCompleteBox и INotifyDataErrorInfo в Silverlight

Я успешно создал стандартные TextBoxes и DatePickers, и они ведут себя отлично в соответствии со многими примерами, любезно предоставленными людьми в Интернете.

было бы хорошо, если бы был ответ на этот вопрос для согласованности моего экрана, также потому, что я хотел бы просто привязать свойство HasErrors, которое поставляется с INotifyDataErrorInfo, чтобы включить кнопку, когда она готова к сохранению, и я могу " t сделать это без дополнительного кода, чтобы проверить правильность этих полей.

В настоящее время я отношусь к ним по-другому, используя привязку MVVMLight EventToCommand и регистрацию события LostFocus.

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

В ViewModel я тогда бросил RoutedEventArgs.OriginalSource к TextBox и получите текст, как это так, препятствуя пользователю покинуть поле если он не является пустым или соответствующий элемент в списке бокса: -

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. У меня есть привязка к SelectedItem и Text, но хотя я могу их очистить в ViewModel (т. Е. Null и String.Empty), исходное свойство SearchText для автозаполнения остается и сбрасывает текст на пользовательский ввод (т. Е. Не текст окончательный выбор, но изначально введенные символы, которые вызвали раскрывающийся список). У меня этот вопрос размещен на многих форумах, так как я не могу его отсортировать. – EzaBlade

+0

Попробуйте вызвать OnPropertyChanged внутри свойства и установить Binding as TwoWay. Мой пример реализует эти условия, поэтому он должен решить вашу проблему. Если это не так, вы можете задать новый вопрос с подробным описанием проблемы. – vorrtex

+0

Я решил свою проблему (вызванную мной). – EzaBlade

Смежные вопросы