SilverlightのAutoCompleteBoxおよびInotifyDataerrorinfo
-
26-10-2019 - |
質問
inotifydataerrorinfoインターフェイスを正常に適用し、autocompleteboxにバインドした人はいません。私はこれを試しましたが、応答はありません。コントロールは、他のコントロール、つまり赤い境界線と警告ツールチップのように応答しません。また、エラーのある検証概要コントロールディスプレイも作成しません。
私は標準のテキストボックスとデートピッカーを正常にセットアップしましたが、これらはインターネット上の人々が親切に提供する多くの例に従って完全に振る舞います。
画面の一貫性についてこれに答えがあった場合は、InotifyDataerrorinfoに付属するHaserrorsプロパティに単純にバインドしたいので、それは良いことです。これらのボックスが正しいことを確認するための追加コード。
現時点では、MVVMLight EventToCommand Bindingを使用して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をテキストボックスにキャストし、そのようなテキストを取得します。ユーザーがボックスのリストに空になったり一致していない限り、ユーザーがボックスを離れるのを防ぎます。
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();
}
}
解決
私はできる限り簡単な例を書こうとしました。私のモデルは、プロパティ検索テキストの変更と検証プロパティを更新します。
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"/>
コントロールには赤い境界線があり、モデルにエラーがあるときにボタンが無効になります。
所属していません StackOverflow