Сделайте границу ComboBox красной, если элемент еще не выбран

Я новичок в C# и WPF и, честно говоря, начал учиться самостоятельно только на этой неделе. Я пытаюсь создать раскрывающееся меню, которое будет выделено красным (сигнализируя, что это поле является обязательным), пока не будет выбран элемент. В моем списке нет пустого элемента, но состояние по умолчанию — пустой вариант. После выбора одного элемента вы не сможете снова получить доступ к пустой опции.

Я попробовал кучу разных подходов и считаю, что понимаю, что мне нужно создать шаблон стиля, который запрашивает проверку для изменения цвета границы. Однако я сталкиваюсь с некоторыми проблемами. Он никогда не видит ошибок проверки при запуске. Я думаю, что у меня просто фундаментальное непонимание того, как использовать проверки (в основном, синтаксические требования к созданию моей собственной проверки и ее использованию для этого триггера).

Если есть какой-либо способ сделать это без проверок, это может быть проще для меня, но я не видел в Интернете ничего, описывающего это. Любая помощь будет оценена по достоинству.

Мой стиль шаблона XAML ComboBox:

 <Style x:Key = "ComboBoxValidationStyle" TargetType = "ComboBox">
     <Setter Property = "Template">
         <Setter.Value>
             <ControlTemplate TargetType = "ComboBox">
                 <Border x:Name = "border" BorderBrush = "Green" BorderThickness = "1">
                     <ComboBox x:Name = "PART_EditableTextBox"
                               ItemsSource = "{TemplateBinding ItemsSource}" 
                               SelectedItem = "{Binding SelectedModelNumber, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}">
                     </ComboBox>
                 </Border>
                 <ControlTemplate.Triggers>
                     <Trigger Property = "Validation.HasError" Value = "True">
                         <Setter Property = "ToolTip" Value = "{Binding RelativeSource = {RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                         <Setter Property = "BorderBrush" TargetName = "border" Value = "Red"/>
                         <Setter Property = "BorderThickness" TargetName = "border" Value = "1"/>
                     </Trigger>
                     <Trigger Property = "IsMouseOver" Value = "True">
                         <Setter Property = "BorderBrush" TargetName = "border" Value = "#00aed7"/>
                     </Trigger>
                 </ControlTemplate.Triggers>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>

МОЙ код XAML ComboBox:

           <ComboBox Grid.Row = "1" FontSize = "15" Grid.Column = "2" Width = "110" Height = "27" Margin = "26,0,0,0" Style = "{StaticResource ComboBoxValidationStyle}" ItemsSource = "{Binding ModelNumbers}" Name = "comboBox1">
               <ComboBox.SelectedItem>
                   <Binding Path = "Name" Mode = "TwoWay" RelativeSource = "{RelativeSource Mode=TemplatedParent}" UpdateSourceTrigger = "PropertyChanged" ValidatesOnDataErrors = "True">
                       <Binding.ValidationRules>
                           <local:SelectionValidationRule></local:SelectionValidationRule>
                       </Binding.ValidationRules>
                   </Binding>
               </ComboBox.SelectedItem>
           </ComboBox>

Мой код проверки:

    public class SelectionValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            if (value is string selectedItemString)
            {
                if (string.IsNullOrEmpty(selectedItemString))
                {
                    return new ValidationResult(false, null);
                }
            }
            else if (value == null || string.IsNullOrEmpty(value.ToString()))
            {
                return new ValidationResult(false, null);
            }
            else if (value is ComboBox comboBox)
            {
                if (comboBox.SelectedIndex == -1)
                {
                    return new ValidationResult(false, null);
                }
            }

            return new ValidationResult(true, null);
        }
    }

И да, я включил класс SelectionValidationRule в свой код XAML!

Пожалуйста, прочитайте blog.magnusmontin.net/2013/08/26/data-validation-in-wpf

Sir Rufo 22.06.2024 07:21

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

emoacht 23.06.2024 02:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

DataTrigger позволяют изменять свойства стиля в соответствии со значениями других свойств. Вы можете автоматически изменить цвет Border в соответствии со значением ComboBoxSelectedIndex, которое начинается с 0 для первого выбираемого элемента и равно -1, если выбор не сделан, что, как я предполагаю, является тем, что вы хотите предотвратить.

Измените тег Border на:

            <Border x:Name = "border" BorderThickness = "1">
              <Border.Resources>
                <Style TargetType = "Border">
                  <Setter Property = "BorderBrush" Value = "Green"/>
                  <Style.Triggers>
                    <DataTrigger Binding = "{Binding SelectedIndex, ElementName=PART_EditableTextBox}" Value = "-1">
                      <Setter Property = "BorderBrush" Value = "Red"/>
                    </DataTrigger>
                  </Style.Triggers>
                </Style>
              </Border.Resources>
              <ComboBox x:Name = "PART_EditableTextBox"
                               ItemsSource = "{TemplateBinding ItemsSource}" 
                               SelectedItem = "{Binding SelectedModelNumber, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}">
              </ComboBox>
            </Border>

И вы можете смело удалить тег ComboBox.SelectedItem и класс SelectionValidationRule, если вам не нужны более строгие меры. Но вышеперечисленное должно быть всем, что вам нужно, чтобы изменить цвет Border. Надеюсь это поможет...

Другие вопросы по теме