WPF Проверка несвязанного текстового поля

можно ли использовать проверку без части Binding? Дело в том, что мое текстовое поле не привязано к какому-либо объекту, но я все еще хочу проверить его содержимое. Единственный способ, который я нашел до сих пор, это:

    <TextBox Grid.Row="0" Grid.Column="1" MaxLength="50" x:Name="textBoxTubeName" Margin="5,5,0,5">
        <TextBox.Text>
            <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" NotifyOnValidationError="True">
                <Binding.ValidationRules>
                    <validation:InvalidCharactersRule />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>

Но опять же, это работает только тогда, когда TextBox.Text привязан к чему-то (в данном случае к свойству Name), как мне это сделать без привязки?

Спасибо!


person Carlo    schedule 28.09.2009    source источник


Ответы (2)


Согласно форумам MSDN это пока невозможно, но планируется (Примечание: это старый пост). Однако я до сих пор не могу найти способ сделать это, поэтому он может быть еще не реализован.

person Kredns    schedule 28.09.2009
comment
Да, я думаю, что мне придется сделать код самостоятельно. Я думаю, что идея Microsoft сосредоточиться на привязке хороша, но ограничение проверки таким образом из-за этой цели не так уж и хорошо. Спасибо, Лукас. - person Carlo; 28.09.2009
comment
Привет. Есть какие-нибудь обновления на эту тему? Я хотел бы сделать то же самое. - person Igor Kondrasovas; 07.08.2015

Это очень сложно сделать из кода программной части. По сути, вы можете установить временную привязку из кода и вызвать ошибку проверки, а когда ввод имеет действительное значение, вы можете снова удалить все временные привязки.

Вот что я использую, что считаю плохой практикой (но лучше из ничего):

    /// <summary>
    /// Marks a textBox control as invalid (via validation error) from code.
    /// </summary>
    /// <param name="textBox">The text box.</param>
    /// <param name="errorContent">Content of the error.</param>
    public static void ValidationMarkInvalid(TextBox textBox, String errorContent)
    {
        DependencyProperty textProp = TextBox.TextProperty;
        if (!BindingOperations.IsDataBound(textBox, textProp))
        {
            if (textBox.DataContext == null)
            {
                textBox.DataContext = new EmptyDataContext();
            }

            Binding b = new Binding("CodeBehind");
            b.FallbackValue = textBox.Text;
            b.ValidatesOnExceptions = true;
            BindingOperations.SetBinding(textBox, textProp, b);
        }

        BindingExpression bindingInError =
            textBox.GetBindingExpression(TextBox.TextProperty);

        var validationError = new ValidationError(
            new EmptyValidationRule(),
            bindingInError,
            errorContent,
            new Exception(errorContent));

        Validation.MarkInvalid(bindingInError, validationError);
    }

    /// <summary>
    /// Clears the validation error from a textBox.
    /// </summary>
    /// <param name="textBox">The text box.</param>
    public static void ValidationClear(TextBox textBox)
    {
        DependencyProperty textProp = TextBox.TextProperty;
        if (BindingOperations.IsDataBound(textBox, textProp))
        {
            String value = textBox.Text;
            Validation.ClearInvalid(textBox.GetBindingExpression(TextBox.TextProperty));
            BindingOperations.ClearBinding(textBox, textProp);
            textBox.Text = value;

            EmptyDataContext ctx = textBox.DataContext as EmptyDataContext;
            if (ctx != null)
            {
                textBox.DataContext = null;
            }
        }
    }

    #region Nested Type: EmptyDataContext
    private sealed class EmptyDataContext : INotifyPropertyChanged
    {
        public Object CodeBehind
        {
            get
            {
                throw new FormatException();
            }
            set
            {
                throw new FormatException();
            }
        }

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }
    #endregion

    #region Nested Type: EmptyValidationRule
    private sealed class EmptyValidationRule : ValidationRule
    {
        /// <summary>
        /// When overridden in a derived class, performs validation checks on a value.
        /// </summary>
        /// <param name="value">The value from the binding target to check.</param>
        /// <param name="cultureInfo">The culture to use in this rule.</param>
        /// <returns>
        /// A <see cref="T:System.Windows.Controls.ValidationResult"/> object.
        /// </returns>
        public override ValidationResult Validate(Object value, CultureInfo cultureInfo)
        {
            return new ValidationResult(false, String.Empty);
        }
    }
    #endregion

Теперь из вашего кода вы делаете это:

ValidationMarkInvalid(textBox, "Please enter something valid!");

и очистить проверку:

ValidationClear(textBox);

P.S.: Если вы не хотите проверять исключения, вы можете удалить класс EmptyDataContext из вышеуказанных методов.

person Nikos Baxevanis    schedule 28.12.2010