Проверка пустого текстового поля

У меня есть три текстовых поля в моем приложении wpf. Когда пользователь вводит значение в эти текстовые поля и нажимает Add, они добавляются в список и отображаются в сетке данных.

Текстовые поля не привязаны ни к чему как таковому, и я добавляю эти значения текстовых полей в коллекцию наблюдения, привязанную к сетке данных. Я хочу запретить пользователю вводить пустые значения в текстовые поля. Как это делается?

Я видел несколько примеров, но все они имели текстовое поле, привязанное к значениям, а затем использовали Binding.Validation. Как это будет сделано в моем случае, когда есть привязка к текстовому полю?

У меня также есть кнопка, которая должна быть заморожена при вводе пустых значений. для этого я использовал следующий подход, создав класс и привязав класс следующим образом;

<Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="IsEnabled" Value="false" />
                    <Style.Triggers>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding ElementName=textBox1, Path=(Validation.HasError)}" Value="false" />
                                <Condition Binding="{Binding ElementName=textBox2, Path=(Validation.HasError)}" Value="false" />
                                <Condition Binding="{Binding ElementName=TextBoxAge, Path=(Validation.HasError)}" Value="false" />                                
                            </MultiDataTrigger.Conditions>
                            <Setter Property="IsEnabled" Value="true" />
                        </MultiDataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>

Класс .cs

 public class TextBoxNotEmptyValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            string str = value as string;
            if (str != null)
            {
                if (str.Length > 0)
                    return ValidationResult.ValidResult;
            }
            return new ValidationResult(false, Message);
        }
        public string Message { get; set; }
    }

person user1240679    schedule 01.08.2012    source источник
comment
Почему бы не привязать ваши текстовые поля к значениям, как в примерах, которые вы видели? Это побудит вас к более структурированному коду, который принесет вам пользу в долгосрочной перспективе.   -  person Dan Puzey    schedule 01.08.2012
comment
@DanPuzey: Можете ли вы объяснить, как будет происходить эта привязка и значения будут добавлены в наблюдаемую коллекцию? Я как-то не понял этой концепции ;-/   -  person user1240679    schedule 01.08.2012


Ответы (1)


Если я вас правильно понял, вы ищете что-то вроде этого:

<Button.Style>
    <Style TargetType="{x:Type Button}">
        <Setter Property="IsEnabled" Value="True" />
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Text, ElementName=textBox1}" Value="{x:Static s:String.Empty}" />
                    <Condition Binding="{Binding Text, ElementName=textBox2}" Value="{x:Static s:String.Empty}" />
                    <Condition Binding="{Binding Text, ElementName=TextBoxAge}" Value="{x:Static s:String.Empty}" />
                </MultiDataTrigger.Conditions>
                <Setter Property="IsEnabled" Value="False" />
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
</Button.Style>

Добавить это пространство имен

xmlns:s="clr-namespace:System;assembly=mscorlib"

Обновить

Тогда это будет работать:

<Button.Style>
    <Style TargetType="{x:Type Button}">
        <Style.Resources>
            <local:MyTextValidationConverter x:Key="MyTextValidationConverter" />
        </Style.Resources>
        <Setter Property="IsEnabled">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource MyTextValidationConverter}">
                    <Binding Path="Text" ElementName="textBox1" />
                    <Binding Path="Text" ElementName="textBox2" />
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
</Button.Style>

И этот код преобразователя

public class MyTextValidationConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string text1 = values[0] as string;
        if (string.IsNullOrEmpty(text1)) return false;

        string text2 = values[1] as string;
        if (string.IsNullOrEmpty(text2)) return false;

        return true;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
person LPL    schedule 01.08.2012
comment
Похоже, заполнение одного из текстовых полей включает кнопку. Я хочу обеспечить непустую проверку для двух из этих текстовых полей. - person user1240679; 01.08.2012
comment
Укажите, что вы хотите. Какие два текстовых поля? И вы хотите, чтобы кнопка была включена, если обе не пустые или только одна? - person LPL; 01.08.2012
comment
textBox1 и textBox2 не должны принимать пустые входные данные. Оба должны быть заполнены пользователем до включения кнопки. Хотя третье текстовое поле может быть пустым - person user1240679; 01.08.2012
comment
Жаль, потому что нет ни Or-MultiDataTrigger, ни какой-либо проверки на NotEmpty. Я отредактировал свой ответ с помощью решения MultiBinding. - person LPL; 01.08.2012
comment
И это должно быть лучше, чем использование кода для выполнения этих задач? WPF поражает меня... Вы заменили один оператор if примерно 40 строками ерунды. - person Ed S.; 01.08.2012
comment
@ЭдС. Если бы он следовал за MVVM, это было бы почти так же просто. - person LPL; 01.08.2012
comment
@LPL: ... Мне просто нравится разглагольствовать о WPF, не принимайте меня слишком серьезно: D. Я не выношу тот факт, что они усложняют простые задачи, чтобы облегчить ранее сложные задачи. - person Ed S.; 01.08.2012
comment
@LPL: Можете ли вы упомянуть, как было бы проще (более легко) с MVVM, потому что я сейчас следую шаблону - person user1240679; 01.08.2012
comment
@LPL: И вместо Oe MultiData Trigger есть триггер и multidata, чтобы я мог сделать все текстовые поля обязательными - person user1240679; 01.08.2012
comment
MultiDataTrigger по умолчанию имеет значение И. Все условия должны быть истинными для срабатывания. В MVVM вы должны привязать все свойства TextBox.Text и Button.IsEnabled к соответствующим свойствам в ViewModel, которые вы установили как DataContext вашего представления. Затем в ViewModel вы можете получить доступ ко всем необходимым строкам, чтобы вычислить, должна ли кнопка быть включена get { return !string.IsNullOrEmpty(text1) && !string.IsNullOrEmpty(text2); }. Или вы используете команды ... - person LPL; 01.08.2012