簡體   English   中英

WPF Datagrid 新行驗證

[英]WPF Datagrid new row validation

我用 DataGrid 制作了一個簡單的 WPF 應用程序,它使用 Employee 對象綁定到 List:

public class Employee
{
    private string _name;

    public int Id { get; set; }


    public string Name
    {
        get { return _name; }
        set
        {
            if (String.IsNullOrEmpty(value))
                throw new ApplicationException("Name cannot be empty. Please specify the name.");
            _name = value;
        }
    }

如您所見,我想防止在沒有設置 Name 屬性的情況下創建員工。 所以,我制定了一個驗證規則:

public class StringValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string str = value as string;
        if (String.IsNullOrEmpty(str))
            return new ValidationResult(false, "This field cannot be empty");
        else
            return new ValidationResult(true, null);
    }
}

名稱字段的 XAML 如下:

<DataGridTextColumn Header="Name" 
                                ElementStyle="{StaticResource datagridElStyle}" >
                <DataGridTextColumn.Binding>
                    <Binding Path="Name" Mode="TwoWay" NotifyOnValidationError="True" ValidatesOnExceptions="True" UpdateSourceTrigger="PropertyChanged" >
                        <Binding.ValidationRules>
                            <emp:StringValidationRule/>
                        </Binding.ValidationRules>
                    </Binding>
                </DataGridTextColumn.Binding>
            </DataGridTextColumn>

如果我嘗試在 DataGrid 中編輯現有員工行的名稱並將其設置為空字符串,datagrid 會標記錯誤的字段並且不允許保存行。 這是正確的行為。

但是,如果我創建一個新行並在鍵盤上按 Enter 鍵,則會創建這個新行,並將 _name 設置為 NULL,並且驗證不起作用。 我猜這是因為 DataGrid 為新行 object 調用了默認構造函數,並將 _name 字段設置為 NULL。

驗證新行的正確方法是什么?

您可以在您的Employee object 上實現IDataError 這里有一個很好的頁面。

我實際上遇到了同樣的問題,但是因為我一直在使用 MVC 數據注釋,如 Karl Shifflett 所示: http://bit.ly/18NCpJU 我最初認為這是一個好主意,但我現在意識到可能是 Microsoft 的意圖不包括 MVC 數據注釋,因為這些似乎更適合提交表單,但不適用於數據持續存在且可以在其中進行編輯的應用程序會議,但我離題了..

這是我為臨時解決方法所做的。 長期的解決方案是實現 IDataError:

// BusinessEntityBase is what allows us to
// use MVC Data Annotations ( http://bit.ly/18NCpJU )
public class MyModel : BusinessEntityBase
{
    private string _name;
    private List<Action> _validationQueue = new List<Action>();
    private Timer _timer = new Timer { Interval = 500 };

    [Required( AllowEmptyStrings = false )]
    public string Name
    {
        get
        {
            return this._name;
        }
        set
        {
            var currentValue = this._name;
            this._name = value;
            base.RaisePropertyChanged("Name");

            this.AddValidationAction( "Name", currentValue, value  );
        }
    }

    private void AddValidationAction<T>( string Name,  T currentValue, T newValue)
    {
        Action validationAction = 
            () => 
                base.SetPropertyValue( Name, ref currentValue, newValue );
        _validationQueue.Add(validationAction);
        this._timer.Enabled = true;
    }

    private void ProcessValidationQueue(object sender, ElapsedEventArgs e)
    {
        if( _validationQueue.Count > 0 )
        {
            while ( _validationQueue.Count > 0)
            {
                _validationQueue[0].Invoke();
                _validationQueue.RemoveAt( 0 );
            }
        }

        this._timer.Enabled = false;
    }

    public MyModel()
    {
        _timer.Enabled = false;
        _timer.Elapsed += this.ProcessValidationQueue;
        _timer.Start();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM