【问题标题】:Validation when binding data in WPF在 WPF 中绑定数据时的验证
【发布时间】:2012-02-01 08:46:45
【问题描述】:

我在 WPF (MVVM) 中构建了一个应用程序并添加了验证。这是我的结果:

您会注意到输入文本框周围的红色乡绅。问题是我不想在启动表单时遇到验证错误的客户。输入数据或按提交时最好。

关于 SO 有一些类似的问题,但没有找到合适的解决方案。 (在初始化时重置每个控件是没有解决方案的)

所以问题是如何启动表单和:

选项 A:(轻松)重置验证

选项 B:在绑定之前不要调用验证

选项 C:其他不错的解决方案

下载代码:

here

查看代码:

<Window x:Class="Validation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="150" Width="250">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="80"></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <!-- Name -->
        <Label Grid.Column="0" Grid.Row="0">Name</Label>
        <TextBox Grid.Column="1" Grid.Row="0"
                 Text="{Binding Model.Name, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"></TextBox>
        <!-- Age -->
        <Label Grid.Column="0" Grid.Row="1">Age</Label>
        <TextBox Grid.Column="1" Grid.Row="1"
                 Text="{Binding Model.Age, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"></TextBox>
        <!-- Submit/Cancel -->
        <StackPanel Grid.Column="1" Grid.Row="2" FlowDirection="LeftToRight">
            <Button>Cancel</Button>
            <Button>Submit</Button>
        </StackPanel>
    </Grid>
</Window>

ViewModel 代码:

public class FormViewModel
{
    #region constructors
    public FormViewModel()
    {
        Model = new FormModel();
    }
    #endregion

    #region properties
    public FormModel Model { get; set; }
    #endregion

}

型号代码:

   public class FormModel : INotifyPropertyChanged, IDataErrorInfo
    {
        #region notifypropertychanged
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }
        #endregion

        #region dataerrorinfo
        public string Error
        {
            get { return null; }
        }

        public string this[string columnName]
        {
            get
            {
                switch (columnName)
                {
                    case "Name":
                        if (string.IsNullOrEmpty(Name))
                        {
                            return "Name is required";
                        }
                        break;
                    case "Age":
                        if (Age < 18 || Age > 50)
                        {
                            return "Are you kidding?";
                        }
                        break;
                }
                return null;
            }
        }
        #endregion

        #region properties
        private string name;
        public string Name { get { return name; } set { name = value; OnPropertyChanged("Name"); } }

        private int age;
        public int Age { get { return age; } set { age = value; OnPropertyChanged("Age"); } }
        #endregion
    }

解决方案(目前)

<Style x:Key="InputControlDefault" TargetType="{x:Type TextBox}">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel LastChildFill="True">
                    <TextBlock DockPanel.Dock="Right" 
                    Foreground="black"
                    FontSize="12pt">
                    ?
                    </TextBlock>
                    <AdornedElementPlaceholder/>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Foreground" Value="Black"/>
        </Trigger>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip" Value="test"/>
            <Setter Property="BorderBrush" Value="Red" />
        </Trigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="Validation.HasError" Value="true"/>
                <Condition Property="Text" Value=""/>
            </MultiTrigger.Conditions>
            <Setter Property="BorderBrush" Value="Orange" />
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <DockPanel LastChildFill="True">
                            <TextBlock DockPanel.Dock="Right" Foreground="Black" FontSize="12pt">
                                *
                            </TextBlock>
                            <AdornedElementPlaceholder/>
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="ToolTip" Value="test"/>
        </MultiTrigger>
    </Style.Triggers>
</Style>

【问题讨论】:

    标签: wpf validation mvvm


    【解决方案1】:

    几天前我回答了一个类似的问题:

    首先,如果您的规则说名字和姓氏不应为空 - 用户看到验证错误是正确的。

    我所做的是将 ValidationTemplate 用于空/初始值,所以 用户只看到所需字段的“*”。

    here 是完整的答案

    【讨论】:

    • 我很喜欢你的方法,会试试看。
    • 试了一下并在问题中添加了结果。
    猜你喜欢
    • 1970-01-01
    • 2012-12-22
    • 2013-10-30
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多