1

私はWPFが初めてです。フォームのデータ コンテキストにはStartTimeEndTimeフィールド (MVVM を使用) が含まれており、これらを独自のテキスト ボックスにバインドすることに成功しました。StartTime新しいユーザーが入力した値の前にあることを確認する検証を作成しようとしていEndTimeます。EndTime次のコードは、フィールドを検証パラメーターにバインドしていないようですMaximum

XAML:

<TextBox>
    <TextBox.Text>
        <Binding Path="StartTime" UpdateSourceTrigger="LostFocus" StringFormat="{}{0:hh}:{0:mm}">
            <Binding.ValidationRules>                                            
                <local:ValidateTime>
                    <local:ValidateTime.Maximum>
                        <local:ValidationParameter Parameter="{Binding EndTime, StringFormat=hh\\:mm}" />
                    </local:ValidateTime.Maximum>
                </local:ValidateTime>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

モデルを見る:

public class ValidationParameter : DependencyObject
{
    public static readonly DependencyProperty ParameterProperty = DependencyProperty.Register(
        "Parameter",
        typeof(string),
        typeof(ValidationParameter),
        new FrameworkPropertyMetadata(null));

    public string Parameter
    {
        get { return (string)GetValue(ParameterProperty); }
        set { SetValue(ParameterProperty, value); }
    }
}

public class ValidateTime : ValidationRule
{
    private TimeSpan _Minimum = new TimeSpan(0, 0, 0);
    private TimeSpan _Maximum = new TimeSpan(23, 59, 9);
    private ValidationParameter _MinimumProperty;
    private ValidationParameter _MaximumProperty;

    public ValidationParameter Minimum
    {
        get
        {
            return _MinimumProperty;
        }
        set
        {
            TimeSpan ts;
            if (TimeSpan.TryParse(value.Parameter, out ts))
            {
                _Minimum = ts;
                _MinimumProperty = value;
            }
        }
    }

    public ValidationParameter Maximum
    {
        get 
        {
            return _MaximumProperty;
        }
        set 
        {
            TimeSpan ts;
            if (TimeSpan.TryParse(value.Parameter, out ts))
            {
                _Maximum = ts;
                _MaximumProperty = value;
            }
        }
    }

    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        string formattedValue = value.ToString();
        if (Regex.IsMatch(formattedValue, @"^\d{4}$"))
        {
            formattedValue = string.Format("{0}:{1}", formattedValue.Substring(0, 2), formattedValue.Substring(2, 2));
        }
        TimeSpan convertedValue;
        if (TimeSpan.TryParseExact(formattedValue, "g", System.Globalization.CultureInfo.CurrentCulture, out convertedValue))
        {
            if (convertedValue > _Maximum)
            {
                return new ValidationResult(false, string.Format("Time must be before {0}.", _Maximum.ToString("g")));
            }
            else if (convertedValue < _Minimum)
            {
                return new ValidationResult(false, string.Format("Time must be after {0}.", _Minimum.ToString("g")));
            }
            return ValidationResult.ValidResult;
        }
        else
        {
            return new ValidationResult(false, string.Format("'{0}' is not a valid time entry.", value.ToString()));
        }
    }
}

次のようにパラメーターを静的な値に設定すると、コードは機能しますが、この検証を動的にする必要があります。

<local:ValidateTime.Maximum>
    <local:ValidationParameter Parameter="12:00" />
</local:ValidateTime.Maximum>
4

3 に答える 3

0

おそらく、 がビジュアル ツリーまたは論理ツリーにないという事実に対処する必要があります。これにより、 、およびへのValidationRulesバインドが失敗します。DataContextElementNameRelativeSource

于 2016-03-24T05:35:19.773 に答える
0

私の場合

<local:RangeValidation ValidationStep="UpdatedValue"/>

助けた。したがって、Datacontext を含む DependencyObject を value(.dataitem) として渡し、パラメーターを Validation に渡す必要はありません。BR、ダニエル

ところで、mee のクレジットではなく、見つけたばかりですが、誰がヒントを与えたか思い出せません :)

于 2016-03-30T13:43:37.713 に答える