Comment utiliser ValidatesOnDataErrors sur une zone de texte à l'intérieur d'un ItemsControl
J'essaie d'avoir une zone de texte contenu est validé à l'aide IDataErrorInfo. La source de la liste ci-dessous est une Liste et chaque élément est affiché. Quand j'ai mis ValidatesOnDataErrors=True
dans la Liaison pour le Texte sur la zone de texte, il ne fonctionne pas comme prévu. Comment puis-je faire cela?
<ItemsControl ItemsSource="{Binding Trainings}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel>
<TextBlock Text="{Binding MobileOperator}" />
<TextBlock Text="{Binding LastUpdate}"/>
</StackPanel>
<StackPanel>
<TextBlock Text="Number trained*" />
<!-- ValidatesOnDataErrors doesn't work here-->
<TextBox
Text="{Binding NumberTrained,
ValidatesOnDataErrors=True}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Mise à jour: de Poster une version allégée du Modèle, ViewModel, de la Vue et du Code-behind
ViewModel et le Modèle
public class MyViewModel : IDataErrorInfo, INotifyPropertyChanged
{
public MyViewModel()
{
Trainings = new List<MyModel>
{
new MyModel { NumberTrained = 5, MobileOperator = "MO 1", LastUpdate = DateTime.Now },
new MyModel { NumberTrained = 1, MobileOperator = "MO 2", LastUpdate = DateTime.Now },
};
OkButtonCommand = new ButtonCommand(OnClick);
}
private void OnClick()
{
PropertyChanged(this, new PropertyChangedEventArgs(""));
}
public event PropertyChangedEventHandler PropertyChanged;
public ICommand OkButtonCommand { get; private set; }
public List<MyModel> Trainings { get; private set; }
public string Error { get { return null; } }
public string this[string columnName]
{
get
{
string error = null;
switch (columnName)
{
case "NumberTrained":
error = "error from IDataErrorInfo";
break;
}
return error;
}
}
}
public class MyModel
{
public string MobileOperator { get; set; }
public DateTime LastUpdate { get; set; }
public int NumberTrained { get; set; }
}
public class ButtonCommand : ICommand
{
private Action _handler;
public event EventHandler CanExecuteChanged;
public ButtonCommand(Action handler) { _handler = handler; }
public bool CanExecute(object parameter) { return true; }
public void Execute(object parameter) { _handler(); }
}
Code Derrière
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
DataContext = new MyViewModel();
}
}
Vue
<Canvas x:Name="LayoutRoot" Background="White">
<ItemsControl ItemsSource="{Binding Trainings}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="{Binding MobileOperator}" Margin="15,15,0,0" FontWeight="Bold"/>
<TextBlock Text="{Binding LastUpdate, StringFormat=' - Last Updated: \{0:M/d/yy\}'}"
Margin="5,15,15,0" Foreground="Gray"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="Number trained*" />
<TextBox Width="50" Height="20"
Text="{Binding NumberTrained, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Content="ok" Width="100" Height="20" Canvas.Left="248" Canvas.Top="207" Command="{Binding OkButtonCommand}"/>
</Canvas>
- Ce n'travail, et rien dans votre échantillon suggère qu'il ne serait pas. Pouvez-vous montrer le (dépouillé, s'il vous plaît!) code pour votre
Traning
modèle? Conserver les propriétés pertinentes et les IDataErrorInfo mise en œuvre. C'est là votre erreur, le mensonge, je parie. - Mis à jour avec rayures-bas par exemple votre demande.
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin pour mettre en œuvre
IDataErrorInfo
sur votre Modèle, pas votre ViewModel.Comme c'est maintenant, votre un contrôle de validation est de lancer une erreur quand vous essayez de valider la propriété
MyViewModel.NumberTrained
, qui n'existe pas, donc l'erreur de validation n'est jamais appelé.Je sens la mise en œuvre de
IDataErrorInfo
sur ViewModel est plus approprié plutôt que sur le Modèle.Donc dans votre cas, vous pouvez avoir créé un supplémentaire ViewModel (ex:
MyModelViewModel
) et de l'inclure comme unList<MyModelViewModel>
à l'intérieur deMyViewModel
être utilisé commeItemsSource
.En passant par MVVM, si vous sentez que vous devriez avoir une Vue correspondante pour cela, vous pouvez extraire de la
DataTemplate
de laItemsControl
à une nouvelle XMAL.