Я новичок в 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!
Вы вкладываете ComboBox в ComboBox. Это бессмысленно изначально. Затем вы устанавливаете ValidationRule для внешнего ComboBox, пока видите внутренний ComboBox. Это не сработает в любом случае.
DataTrigger
позволяют изменять свойства стиля в соответствии со значениями других свойств. Вы можете автоматически изменить цвет Border
в соответствии со значением ComboBox
SelectedIndex
, которое начинается с 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
. Надеюсь это поможет...
Пожалуйста, прочитайте blog.magnusmontin.net/2013/08/26/data-validation-in-wpf