none
Как задать validationRules программно для контролов которые генерируются программно на форме (WPF) RRS feed

  • Вопрос

  • Здравствуйте. Подскажите пожалуйста как можно программно в WPF задать проверку на корректность используя ValidationRule . Я пробовал сделать правило которое бы в textbox допускало вводить только цифры которые больше 0.

    Вот оно, но почему то оно не работает

    public class DishInformationRule : ValidationRule
        {
            private int _enteredValue;
            public int EneteredValue
            {
                get { return _enteredValue; }
                set { _enteredValue = value; }
            }
    
            public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
            {
                int entered = 0;
                try
                {
                    if (((string)value).Length > 0)
                        entered = Int32.Parse((String)value);
                }
                catch (Exception e)
                {
                    return new ValidationResult(false, "Введено не число " + e.Message);
                }
    
                if (entered < 0)
                {
                    return new ValidationResult(false, "Должно быть введено положительное число");
                }
                else
                {
                    return new ValidationResult(true, null);
                }
            }
        }


    public WrapPanel AddPocketDishContainer()
            {
                DishInformationRule rule = new DishInformationRule();
    
                WrapPanel panel = new WrapPanel();
                panel.Orientation = Orientation.Horizontal;
                Binding bind = new Binding();
                bind.ValidationRules.Clear();
                bind.ValidationRules.Add(rule.Validate); //тут похоже я не правильно делаю
                TextBox textBox = new TextBox();
                textBox.Width = 50;
                ..............................................................
                return panel;
            }


    И вот вопрос как правильно привязать это правило к TextBox ?

    Чтобы если неправильное значение было введено textbox выделялся красным и писалась бы ошибка .

     
    • Изменено Timur2008 20 мая 2014 г. 5:04

Ответы

  • Ну будем считать, что вы не зря мучились с ValidationRule, так как получили опыт, но в вашей задаче этот опыт не пригодится.

    Для вашей задачи вам понадобится специальный контрол, предназначенный для выбора количества. Вы можете своять его самостоятельно (долго, но обучение) или взять готовый.

    Совсем недавно в один из проектов брал вот это. Шикарная штука. Набор самых разных контролов среди которых есть DoubleUpDown (то что вам нужно).

    Маленькая ремарка. Если вы раньше использовали WinForms, то у вас может быть страх перед использованием сторонних контролов. В WPF можете не боятся тут с этим дела гораздо лучше.


    VB.Net - WPF, WinRT, WP

    • Помечено в качестве ответа Timur2008 20 мая 2014 г. 14:46
    Отвечающий
  • только у меня еще вопрос , я использую стороннюю тему для стилизации внешнего вида контролов. Как они между собой будут взаимодействовать с кастом контролами?? 

    Ну вопросы отдельной тематики лучше задавать в отдельном топике но отвечу тут.

    Так как у того же DoubleUpDown совершенно другой класс, то ваша тема его ни как не затронет, он будет иметь исходный вид.

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


    VB.Net - WPF, WinRT, WP

    • Помечено в качестве ответа Timur2008 20 мая 2014 г. 15:00
    Отвечающий

Все ответы

  • ну про это-то я знаю, можете подсказать как. именно правило валидации прицепить ? Желательно с примером ??
  •  MyData myDataObject = new MyData(DateTime.Now);
                Binding bind = new Binding("MyDataProperty");
                bind.Source = myDataObject;
                bind.Mode = BindingMode.TwoWay;
                bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                bind.ValidationRules.Add(new DishInformationRule());
                BindingOperations.SetBinding(textBox, TextBox.TextProperty, bind);

  • Сделал вот так 

    TextBox textBox = new TextBox();
                Binding bind = new Binding(vmmenu.ValidationResult);
                bind.Source = textBox;
                bind.Mode = BindingMode.TwoWay;
                bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                bind.ValidationRules.Add(new DishInformationRule());
                BindingOperations.SetBinding(textBox, vmmenu.ValidationResult, bind);
                textBox.Width = 50;

    Пишет ошибку на строке BindingOperations.SetBinding - 

    Наиболее подходящий перегруженный метод для System.Windows.Data.BindingOperations.SetBinding(System.Windows.DependencyObject, System.Windows.DependencyProperty, System.Windows.Data.BindingBase)" имеет несколько недопустимых аргументов

    Само DependencyProperty выглядит так 

     public string ValidationResult
            {
                get { return (string)GetValue(ValidationResultProperty); }
                set { SetValue(ValidationResultProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for ValidationResult.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty ValidationResultProperty =
                DependencyProperty.Register("ValidationResult", typeof(string), typeof(VMMenuProducts));
    
            


    Как правильно сделать ?? :(( 

  • BindingOperations.SetBinding(vmmenu, vmmenu.ValidationResultProperty, bind);

  • Пишет ошибку "Доступ к члену "DishTravel.ViewModelProducts.VMMenuProducts.ValidationResultProperty" через ссылку на экземпляр невозможен; вместо этого уточните его, указав имя типа." и подчеркивает vmmenu.ValidationResultProperty :((  Попробовал там string поставить тоже ошибку пишет :( 
  • BindingOperations.SetBinding(vmmenu, DishTravel.ViewModelProducts.VMMenuProducts.ValidationResultProperty, bind);

  • Спасибо за помощь. теперь компилиться нормально, но увы эти правила не срабатывают. Всеравно textbox пропускает корявые символы и все валиться с эксепшеном :((
  • Спасибо за помощь. теперь компилиться нормально, но увы эти правила не срабатывают. Всеравно textbox пропускает корявые символы и все валиться с эксепшеном :((

    Вы изначально не совсем правильно поняли суть ValidationRule.

    Он работает так - у вас есть класс поле которого биндится к TextBox. Вы прописываете правило и когда я в TextBox вводится символ не пропускаемый правилом, TextBox получает красную обводку (при стандартном шаблоне) а поле класса не обновляется, то есть не приемлемые данные в модель данных не попадают.

    Если вы хотите, что бы в TextBox в принципе нельзя было вводить какие либо символы, то это совсем другая история...


    VB.Net - WPF, WinRT, WP

    Отвечающий
  • да , кажется постепенно начинает доходить. Спасибо, но как мне тогда это сделать ? Я не хочу просто в коде ставить заглушку вроде Messagebox.show , мне бы хотелось проверять корректность данных именно средствами wpf. В самом xaml я не смогу эту разметку поставить так как контролы генерируются программно.

    • Изменено Timur2008 20 мая 2014 г. 13:30
  • Ну тут все просто )

    VB.Net - WPF, WinRT, WP

    Отвечающий
  • Извините за тупость , но там первый пример который на msdn ведет я по нему правила валидации и сделал. А потом эти правила попытался прицепить к текстбоксу как написано выше, это не работает. :( Можете скинуть какойнибудь пример в котором программно создается текстбокс и к нему примеряются правила валидациии (так чтобы сам текстбокс как то реагровал на некорректные данные, там выделялся красной рамкой или еще как нибудь??:(
    • Изменено Timur2008 20 мая 2014 г. 14:02
  • Я пишу на VB.Net, поэтому мой пример вам не поможет.

    Давайте сначала - чего конкретно вы хотите добиться (не какие классы использовать), а в чем задача.

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


    VB.Net - WPF, WinRT, WP

    Отвечающий
  • У меня есть программа в ней есть продукты (они выбираются из комбобокса) и рядом с комбобоксом есть тестбокс в него пользователь вводит количество таких продуктов. Если ему нужен еще какой то продукт , он нажимает на на баттон и генерируется еще одна пара текстбокс + комбобокс, и так хотть скольо этих пар может быть. Потом пользователь  нажимает на баттон "Посчитать" и в результате ему считаются все значения. Каждого продукта - количество. На самом деле там будет еще одно правило , "пользователь не должен выбирать в двух комбобоксах один и тот же продукт " ему должна выдастся ошибка о том что такой продукт уже был выбран. 

    Задача : нужно после того как пользователь нажмет кнопку "Посчитать" все текст боксы у которых вместо положительного чиста стоит чтото другое выделяться красным цветом и будет написана подсказка о том что там не так. Также с комбобоксами те комбобоксы у которых пользователь выбрал одинаковые продукты выдастся ошибка что выбрано несколько одинаковых продуктов и они будут подсвечены красным цветом.


    • Изменено Timur2008 20 мая 2014 г. 14:29
  • Ну будем считать, что вы не зря мучились с ValidationRule, так как получили опыт, но в вашей задаче этот опыт не пригодится.

    Для вашей задачи вам понадобится специальный контрол, предназначенный для выбора количества. Вы можете своять его самостоятельно (долго, но обучение) или взять готовый.

    Совсем недавно в один из проектов брал вот это. Шикарная штука. Набор самых разных контролов среди которых есть DoubleUpDown (то что вам нужно).

    Маленькая ремарка. Если вы раньше использовали WinForms, то у вас может быть страх перед использованием сторонних контролов. В WPF можете не боятся тут с этим дела гораздо лучше.


    VB.Net - WPF, WinRT, WP

    • Помечено в качестве ответа Timur2008 20 мая 2014 г. 14:46
    Отвечающий
  • Понял, спасибо. Похоже это действительно единственный вариант . Буду пробовать. 
  • только у меня еще вопрос , я использую стороннюю тему для стилизации внешнего вида контролов. Как они между собой будут взаимодействовать с кастом контролами?? 
  • только у меня еще вопрос , я использую стороннюю тему для стилизации внешнего вида контролов. Как они между собой будут взаимодействовать с кастом контролами?? 

    Ну вопросы отдельной тематики лучше задавать в отдельном топике но отвечу тут.

    Так как у того же DoubleUpDown совершенно другой класс, то ваша тема его ни как не затронет, он будет иметь исходный вид.

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


    VB.Net - WPF, WinRT, WP

    • Помечено в качестве ответа Timur2008 20 мая 2014 г. 15:00
    Отвечающий
  • Понял спасибо, буду пробовать:)