簡體   English   中英

將自定義類與 WPF 中的驗證綁定

[英]Bind custom class with Validation in WPF

我注意到可以將 DateTime 類型的變量綁定到 WPF 中的文本框。 如果我輸入錯誤的值,它不會驗證並顯示紅色邊框。

如何實現我自己的類,我可以綁定到文本框而不必綁定到類的屬性? 文本框應顯示一個字符串,該類將驗證輸入。

這可能嗎?

我目前的解決方案是這樣的:

在模型中:

public string DefaultLanguageValue
        {
            get
            {
                return _defaultLanguageValue;
            }
            set
            {
                if (value != this._defaultLanguageValue)
                {
                    ValidateLanguage(value);
                    this._defaultLanguageValue = value;
                    NotifyPropertyChanged();
                }
            }
        }

        
        private void ValidateLanguage(string value)
        {
            string rx = "([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*";
            if (!Regex.IsMatch(value, rx))
            {
                throw new ArgumentException();
            }
        }

在 XAML 中:

<TextBox Text="{Binding TreeViewModel.Model.DefaultLanguageValue, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True}" BorderThickness="0" MinWidth="100"/>

擁有一個我可以像 String、Int 或 DateTime 一樣綁定的類會很好,例如。 有任何想法嗎?

您可以綁定到TextBox本身的Tag屬性並使用ValidationRule

public class DateValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        if (!DateTime.TryParse(value as string, out DateTime _))
            return new ValidationResult(false, "Invalid date...");

        return ValidationResult.ValidResult;
    }
}

XAML:

<TextBox>
    <TextBox.Text>
        <Binding Path="Tag" RelativeSource="{RelativeSource Self}"
                         UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:DateValidationRule />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

這不需要您綁定到視圖模型。

我終於嘗試了mm8建議的解決方案。

我現在唯一的問題是,如果在文本框中輸入無效值,當我在單擊按鈕后以編程方式更改源的值時,它不會更新文本框。

我在更新后嘗試了驗證,但這允許用戶保存無效值。

<TreeViewItem>
                        <TreeViewItem.Header>
                            <StackPanel Orientation="Horizontal">
                                <CheckBox x:Name="chkDefaultLanguage" IsChecked="{Binding TreeViewModel.TreeModel.DefaultLanguage, UpdateSourceTrigger=PropertyChanged}"/>
                                <TextBlock Text="DefaultLanguage: "  />
                                <TextBox BorderThickness="0" MinWidth="100">
                                    <TextBox.Text>
                                        <Binding Path="TreeViewModel.TreeModel.DefaultLanguageValue" UpdateSourceTrigger="PropertyChanged">
                                            <Binding.ValidationRules>
                                                <validationrules:LanguageCodeValidationRule/>
                                            </Binding.ValidationRules>
                                        </Binding>
                                    </TextBox.Text>
                                </TextBox>
                            </StackPanel>
                        </TreeViewItem.Header>
                    </TreeViewItem>
class LanguageCodeValidationRule : ValidationRule
    {
        
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            string rx = "([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*";
            if (!Regex.IsMatch(value.ToString(), rx))
            {
                return new ValidationResult(false, "Invalid Language Codee.");
            }  
            return ValidationResult.ValidResult;
        }
    }

暫無
暫無

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

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