Проверка WPF для всей формы - PullRequest
       10

Проверка WPF для всей формы

14 голосов
/ 19 сентября 2008

Я был серьезно разочарован системой проверки WPF. Тем не мение! Как я могу проверить полную форму, нажав на кнопку?

Почему-то в WPF все так сложно! Я могу сделать проверку в 1 строку кода в ASP.NET, который требует примерно 10-20 строк кода в WPF !!

Я могу сделать это, используя собственную платформу ValidationEngine:

Customer customer = new Customer();
customer.FirstName = "John";
customer.LastName = String.Empty;

ValidationEngine.Validate(customer);

if (customer.BrokenRules.Count > 0)
{
   // do something display the broken rules! 
}

Ответы [ 5 ]

26 голосов
/ 08 октября 2008

Приложение WPF должно отключить кнопку для отправки формы, если введенные данные неверны. Вы можете достичь этого, внедрив интерфейс IDataErrorInfo в свой бизнес-объект, используя привязки с ValidatesOnDataErrors=true. Для настройки внешнего вида отдельных элементов управления в случае ошибок установите значение Validation.ErrorTemplate.

XAML:

<Window x:Class="Example.CustomerWindow" ...>
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Save"
                        CanExecute="SaveCanExecute"
                        Executed="SaveExecuted" />
    </Window.CommandBindings>
    <StackPanel>
        <TextBox Text="{Binding FirstName, ValidatesOnDataErrors=true, UpdateSourceTrigger=PropertyChanged}" />
        <TextBox Text="{Binding LastName, ValidatesOnDataErrors=true, UpdateSourceTrigger=PropertyChanged}" />
        <Button Command="ApplicationCommands.Save" IsDefault="True">Save</Button>
        <TextBlock Text="{Binding Error}"/>
    </StackPanel>
</Window>

Это создает Window с двумя TextBox, где вы можете редактировать имя и фамилию клиента. Кнопка «Сохранить» доступна только в том случае, если не было ошибок проверки. TextBlock под кнопкой показывает текущие ошибки, поэтому пользователь знает, что случилось.

По умолчанию ErrorTemplate представляет собой тонкую красную рамку вокруг ошибочного элемента управления. Если это не вписывается в вашу визуальную концепцию, обратитесь к статье Проверка в Windows Presentation Foundation , посвященной CodeProject, для углубленного изучения того, что можно с этим сделать.

Чтобы окно действительно заработало, в Window и Customer должна быть небольшая инфраструктура.

Код позади

// The CustomerWindow class receives the Customer to display
// and manages the Save command
public class CustomerWindow : Window
{
    private Customer CurrentCustomer;
    public CustomerWindow(Customer c) 
    {
        // store the customer for the bindings
        DataContext = CurrentCustomer = c;
        InitializeComponent();
    }

    private void SaveCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = ValidationEngine.Validate(CurrentCustomer);
    }

    private void SaveExecuted(object sender, ExecutedRoutedEventArgs e) 
    {
        CurrentCustomer.Save();
    }
}

public class Customer : IDataErrorInfo, INotifyPropertyChanged
{
    // holds the actual value of FirstName
    private string FirstNameBackingStore;
    // the accessor for FirstName. Only accepts valid values.
    public string FirstName {
        get { return FirstNameBackingStore; }
        set {
            FirstNameBackingStore = value;
            ValidationEngine.Validate(this);
            OnPropertyChanged("FirstName");
        }
    }
    // similar for LastName        

    string IDataErrorInfo.Error {
        get { return String.Join("\n", BrokenRules.Values); }
    }

    string IDataErrorInfo.this[string columnName]
    {
        get { return BrokenRules[columnName]; }
    }
}

Очевидным улучшением было бы перемещение реализации IDataErrorInfo вверх по иерархии классов, поскольку она зависит только от ValidationEngine, но не от бизнес-объекта.

Хотя это действительно больше кода, чем простой пример, который вы предоставили, он также имеет немного больше функциональности, чем только проверка на достоверность. Это дает вам детализированные и автоматически обновляемые указания пользователю о проблемах проверки и автоматически отключает кнопку «Сохранить», пока пользователь пытается ввести неверные данные.

2 голосов
/ 19 сентября 2008

Я бы посоветовал взглянуть на интерфейс IDataErrorInfo вашего бизнес-объекта. Также взгляните на эту статью: Текстовое поле самоутверждения

1 голос
/ 24 ноября 2010

ValidatesOnDataError используется для проверки бизнес-правил в соответствии с вашими моделями представлений и будет проверяться только в случае успешного связывания.

ValidatesOnExceptions необходимо применять вместе с ValidatesOnDataError для обработки тех сценариев, в которых wpf не может выполнить привязку из-за несоответствия типов данных. Допустим, вы хотите привязать TextBox к свойству Age (целое число) в модели представления

<TextBox Text="{Binding Age, ValidatesOnDataErrors=true, UpdateSourceTrigger=PropertyChanged}" />

Если пользователь вводит недопустимую запись, набирая алфавиты, а не числа как возраст, скажем, xyz, привязка данных wpf будет молча игнорировать значение, поскольку не может связать xyz с возрастом, и ошибка привязки будет потеряна, если привязка не будет украшена ValidatesOnExceptions

<TextBox Text="{Binding Age, ValidatesOnDataErrors=true, ValidatesOnExceptions="True", UpdateSourceTrigger=PropertyChanged}" />

ValidatesOnException использует обработку исключений по умолчанию для ошибок привязки с использованием ExceptionValidationRule, приведенный выше синтаксис является краткой формой для следующего

<TextBox>
    <TextBox.Text>
        <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
            <Binding.ValidationRules>
                  <ExceptionValidationRule />
             </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

Вы можете определить свои собственные правила для проверки в соответствии с пользовательским вводом, наследуя от ValidationRule и реализуя метод Validate, NumericRule в следующем примере

<TextBox.Text>
 <Binding Path="Age" ValidatesOnDataErrors="True">
   <Binding.ValidationRules>
        <rules:NumericRule />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>

Правила проверки должны быть общими и не привязанными к бизнесу, так как последующие действия выполняются через IDataErrorInfo и ValidatesOnDataError.

Приведенный выше синтаксис является довольно запутанным по сравнению с имеющимся у нас синтаксисом однострочного связывания. Благодаря реализации ValidationRule в качестве присоединенного свойства синтаксис может быть улучшен, и вы можете взглянуть на него здесь

1 голос
/ 16 августа 2010

Вас может заинтересовать BookLibrary пример приложения WPF Application Framework (WAF) . В нем показано, как использовать проверку в WPF и как управлять кнопкой «Сохранить» при наличии ошибок проверки.

0 голосов
/ 01 октября 2008

Описание вашей проблемы немного расплывчато для меня. Я имею в виду, я не совсем уверен, в чем твоя сложность. Предполагая, что DataContext является своего рода презентатором или контроллером, который имеет пропетрию, представляющую экземпляр клиента, а ValidateCommand является свойством типа ICommand:

  <StackPanel>  
    <TextBox Text="{Binding CurrentCustomer.FirstName}" />
    <TextBox Text="{Binding CurrentCustomer.LastName}" />
    <Button Content="Validate" 
            Command="{Binding ValidateCommand}"
            CommandParameter="{Binding CurrentCustomer}" />
    <ItemsControl ItemsSource="{Binding CurrentCustomer.BrokenRules}" />
  </StackPanel>

Конечно, этот XAML действительно упрощен, и есть другие способы сделать это. Как веб-разработчик, который в настоящее время тесно связан с WPF, я считаю, что большинство таких задач значительно проще в WPF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...