简体   繁体   中英

Validation in WPF MVVM with Entity Framework

I'm writing a WPF MVVM Light app using Visual Studio 2015. The data has been brought in using Entity Framework 6, using database-first to generate the models. In my MainViewModel.cs file, I'd like to validate the data before doing a SaveChanges() .

The examples I've seen talk about adding annotations to models (for example, this ); however, I'm using auto-generated Entity Framework models. And my ViewModels reference ObservableCollection<Employee> objects -- nothing references fields directly, so that I can put annotations on them.

Here is the SearchResults property, which holds the results returned from EF:

private ObservableCollection<Employee> _searchResults;
public ObservableCollection<Employee> SearchResults
{
    get { return _searchResults; }
    set
    {
        if (_searchResults == value) return;

        _searchResults = value;
        RaisePropertyChanged("SearchResults");
    }
}

The SearchResults gets populated after a search and are bound to a DataGrid:

var query = Context.Employees.AsQueryable();

// Build query here...

SearchResults = new ObservableCollection<Employee>(query.ToList());

The user clicks a row on the DataGrid and we show the details for them to update. They can then hit the Save button. But we want to validate the fields in each Employee before performing Context.SaveChanges() .

Here's the pertinent area of the partial class Employee , auto-generated by Entity Framework:

public int employeeID { get; set; }
public int securityID { get; set; }
public string firstName { get; set; }
public string middleName { get; set; }
public string lastName { get; set; }
public string suffix { get; set; }
public string job { get; set; }
public string organizationalUnit { get; set; }
public string costCenter { get; set; }
public string notes { get; set; }
public System.DateTime createdDate { get; set; }

For example, the securityID must not be blank and it must be an int , while firstName and lastName are required, etc. How do you accomplish this validation and show errors to the user?

I assume when you show user the details you are using TextBox es (You can apply the same solution for other controls).

Instead of validating data after the user changes the properties of Employee , just validate beforehand and don't even change the properties if they are invalid.

You can do this easily with ValidationRule class. For example:

<ListBox ItemsSource="{Binding Employees}" Name="ListBoxEmployees">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"></TextBlock>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
<TextBox>
    <TextBox.Text>
        <Binding ElementName="ListBoxEmployees" Path="SelectedItem.Name" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <stackOverflow:NotEmptyStringValidationRule/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

and the validation rule:

public class NotEmptyStringValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string s = value as string;
        if (String.IsNullOrEmpty(s))
        {
            return new ValidationResult(false, "Field cannot be empty.");
        }

        return ValidationResult.ValidResult;
    }
}

Also you can disable the Save button when any of the validation rules fail.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM