validation - 如何在 ItemsControl 内的 TextBox 上使用 ValidatesOnDataErrors

标签 validation silverlight-4.0 mvvm idataerrorinfo

我正在尝试使用 IDataErrorInfo 验证 TextBox 的内容。下面列表的来源是一个列表,每个项目都是显示的。当我把 ValidatesOnDataErrors=True在 TextBox 上的文本绑定(bind)中,它没有按预期工作。我该怎么做呢?

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

更新:发布模型、 View 模型、 View 和代码隐藏的精简版本

ViewModel 和模型

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(); }
}

代码背后

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();

        DataContext = new MyViewModel();
    }
}

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

最佳答案

我觉得执行IDataErrorInfo在 ViewModel 上比在 Model 上更合适。

因此,在您的情况下,您可以创建一个额外的 ViewModel(例如: MyModelViewModel )并将其包含为 List<MyModelViewModel>里面 MyViewModel用作ItemsSource .

通过MVVM,如果你觉得你应该有一个对应的View,你可以提取出DataTemplateItemsControl到一个新的 XMAL。

关于validation - 如何在 ItemsControl 内的 TextBox 上使用 ValidatesOnDataErrors,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6362083/

相关文章:

c# - mvvmlight 信使奇怪的行为

c# - ObservableCollection 不更新 ListView

php - PHP 中的登录表单验证和错误消息

python - 在 Python 中拒绝列表的快速方法

Silverlight HttpWebRequest.Create 卡在异步 block 内

c# - "Or"Together Expression<Func<EntityFramework Entity, bool>> in .NET 4, Silverlight RIA 域服务

wpf - 如何对 Ribbons ComboBox 的 SelectedItem 进行数据绑定(bind)

javascript - 如何使用 javascript 警报窗口显示验证消息?

javascript - 使用正则表达式允许一位数和两位数范围?

mvvm - BindingMode.TwoWay 不适用于 UserControl (不更新源属性)