在 WPF 中進行表單驗證


WPF的表單驗證,自然比不上WEB多姿多彩。一般有三種方式進行表單驗證:

1. 代碼直接驗證(不少人直接用 MessageBox  彈出消息,Windows 的老傳統),雖然夠醒目,卻太過打擾用戶,不好。

2. 通過異常驗證(數據綁定,並設置 ValidatesOnExceptions=True ),調試時煩死人,不好。

3. 通過內置接口 IDataErrorInfo 、INotifyDataErrorInfo 進行驗證(數據綁定),這應該是目前較為理想的驗證方式。這兩個接口都位於 System.ComponentModel 空間,與 INotifyPropertyChanged 在一起。

 

只說第三種驗證方式。

這兩個接口,個人較喜歡第二個,原因是第一個接口不太靈活,而且是為了兼容而存在的,不推薦使用。第二要靈活得多。

 

為了突出驗證消息的提示效果,可添加這樣一個樣式(定義為字典資源,用起來更方便):

<Style TargetType="TextBox">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel>
                    <TextBlock DockPanel.Dock="Bottom" Foreground="Red"
                                Text="{Binding ElementName=adornedElement, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"></TextBlock>
                    <Border BorderBrush="Red" BorderThickness="1">
                        <AdornedElementPlaceholder Name="adornedElement"></AdornedElementPlaceholder>
                    </Border>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

 

一、首先定義一個集合,用於保存驗證消息:

private readonly IDictionary<string, IList<string>> m_errors = new Dictionary<string, IList<string>>();

 

二、下面是實現接口,具體用法見注釋:

// 該方法僅為簡化屬性調用。CallerMemberName 特性是 .net 4.5 才加入的,位於 System.Runtime.CompilerServices 空間。
public
void Validate(Func<bool> valid, string error, [CallerMemberName]string prop = null) { if (valid()) ClearError(prop); else SetError(new[] { error }, prop); OnChanged(prop); }
// 驗證屬性事件。
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; // 屬性更改事件。
public event PropertyChangedEventHandler PropertyChanged; // 該方法由 wpf 調用。 public IEnumerable GetErrors(string propertyName) { if (string.IsNullOrEmpty(propertyName)) return null;    // SelectMany 方法很有用,若沒有它,錯誤消息不能正確顯示,除非你重寫集合,並重寫其 ToString 方法。它幫你省了很多麻煩。 var errors = m_errors.SelectMany(e => e.Value); return errors; } // 添加錯誤消息。 public void SetError(IList<string> errors, string prop) { m_errors.Remove(prop); m_errors.Add(prop, errors); OnError(prop); } // 清除錯誤消息。 public void ClearError(string prop) { m_errors.Remove(prop); OnError(prop); } // 驗證屬性時調用。 private void OnError(string prop) { ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(prop)); }

 

三、屬性這樣調用驗證代碼(以及更新事件):

public string Password
{
    get { return m_password; }
    set
    {
        m_password = value;
     // 由於第三種驗證方式比較溫和,不能像異常那樣阻止屬性值更新,因此該方法放在下面沒有問題。 Validate(() => !Regex.IsMatch(value, "4"), "數字 4 不祥"); } }

 

四、前台代碼並沒有什么特殊的,只要你別忘了應用上面的樣式。 ValidatesOnNotifyDataErrors=True 可不寫,但建議寫上,有提示作用:

<TextBox Text="{Binding Path=Password, ValidatesOnNotifyDataErrors=True}"></TextBox>

 

完。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM