1

私のアプリケーションは MVVM パターンを使用しています。MyTextBoxは、ViewModel (文字列型) のプロパティにバインドされています。

ユーザーの入力によって内容がTextBox変更されるたびに、何らかの検証を実行したいと考えています。

だから、現在、私のコードは

<TextBox Text="{Binding XmlContentAsString, UpdateSourceTrigger=PropertyChanged}" />

私のViewModelには、このプロパティとフィールドがあります:

        private string _xmlContentAsString;
        public string XmlContentAsString
        {
            get { return _xmlContentAsString; }
            set
            {
                if (_xmlContentAsString == value)
                    return;

                _xmlContentAsString = value;
                PerformValidiationLogic(value);//This is where I am unsure
            }
        }

さて、これは機能しますが、理由はわかりませんが、私はこれが好きではありません! プロパティにメソッドを含めることは、「ハッキング」されているように感じます。

MVVMパターンを使用する場合、これが正しいアプローチであるかどうか教えてください。

4

4 に答える 4

1

さまざまな種類の検証があります。文字列の長さや許可された文字などを単純に検証するには、DataAnnotations を使用して、プロパティの属性に検証を入れることができます。System.ComponentModel.DataAnnotations; を使用して含める必要があります。

たとえば、文字列を 9 文字に保つには、次のようにします。

    [StringLength(9)]
    public string StringValue
    {
        get
        {
            return stringValue;
        }

        set
        {
            this.stringValue = value;
        }
    }

次に、もう少し複雑で、ビジネス ロジックを効果的に適用する検証があります。これを行う方法については多くの意見があるようです。理想的には、検証を再利用できるようにモデルに属している必要がありますが、明らかにビューモデルを介して呼び出されます。

個人的には、ときどきプロパティ セッターにメソッド呼び出しを配置し​​ます。これが、セッターとゲッターを作成できる理由のすべてです。それ以外の場合、自動プロパティ以外のものを使用する意味はほとんどありません。

ただし、複雑または非同期の場合は、問題が発生する可能性があります。UpdateSourceTrigger=PropertyChanged でそれを行うのは非常に慎重です。これは、すべての文字を起動することを意味するためです。

于 2013-04-10T17:18:34.973 に答える
1

あなたの例では、値に対して検証ロジックを実行しますが、失敗した場合、検証の結果はどうなりますか? 通常、検証の失敗をユーザーに通知します。その場合は、IDataErrorInfo をお勧めします (例は次の場所にあります。

http://codeblitz.wordpress.com/2009/05/08/wpf-validation-made-easy-with-idataerrorinfo/ )。

ユーザーに通知せずに値をオーバーライドすることを計画している場合は、setter で検証することは許容されます (ただし、より個人的な理由からファンではありません)。

于 2013-04-10T18:01:12.173 に答える
0

個人的には、プロパティに多くのロジックを入れることはお勧めしません。イベントにバインドされたコマンド、つまりテキストボックスの lostfocus イベントを使用して、そこで検証を実行します。

私は次のようなものを使用します:

 <TextBox Text="{Binding XmlContentAsString, UpdateSourceTrigger=PropertyChanged}">
        <interactivity:Interaction.Triggers>
            <interactivity:EventTrigger EventName="LostFocus">
                <interactivity:InvokeCommandAction Command="{Binding LostFocusCommand, Mode=OneWay}"/>
            </interactivity:EventTrigger>
        </interactivity:Interaction.Triggers>           
    </TextBox>

次に、検証ロジックを使用して LostFocusCommand であるコマンドをビューモデルに配置します。
私は mvvm-light を使用しており、その詳細な例を示すことができます。(xaml の先頭にブレンドの対話性宣言を含める必要があります)

于 2013-04-10T16:03:59.777 に答える
0

私の意見では、それが正しいアプローチです。プロパティを設定するメソッドを含む ViewModel の基本クラスを作成し、PropertyChanged を呼び出して、そのプロパティに何らかの検証規則が添付されているかどうかを検証します。

例えば:

public abstract class ValidableViewModel
{
    private List<ValidationRule> _validationRules;

    public ValidableViewModel()
    {
        _validationRules = new List<ValidationRule>();
    }

    protected virtual void SetValue<T, T2>(Expression<Func<T>> expression,
                                           ref T2 backend, T2 value)
    {
        if (EqualityComparer<T2>.Default.Equals(backend, value))
            return;

        backend = value;
        OnPropertyChanged(expression);

        Validate(expression.Name, value);
    }

    protected void Validate(string propertyName, object value)
    {
        foreach(var validationRule in _validationRules)
        {
            if(validationRule.PropertyName == propertyName)
                validationRule.Execute(value);
        }
    }
}

コードは完全ではなく、多くの行方不明があります。しかし、それは始まりかもしれません;-)

于 2013-04-10T11:06:25.027 に答える