ВВЕДЕНИЕ
Я создал DecimalTextBox UserControl
, который содержит некоторую десятичную проверку, которую мне нужно сделать, так что мне не нужно каждый раз пересматривать проверкуи может просто использовать вместо UserControl
.У этой проверки есть свойства, с которыми нужно связываться, и поэтому я создал DependencyProperties
, чтобы я мог связываться с ними, согласно этой статье Джоша Смита .
ПРОБЛЕМА
Проверка элемента управления ведет себя странно.Когда я набираю ошибочное значение в TextBox
, оно отображается как ошибка.Однако, когда я пытаюсь изменить значение обратно в коде , значение, показанное в текстовом поле, остается неизменным.
Вот шаги, которые я выполняю, которые вызывают эту ошибку (в этом примере 1 являетсянедопустимое значение):
- Загрузить форму и значение по умолчанию: 0 .
- Введите 1 в текстовое поле (и текстовое поле).идет красный из-за результата проверки и ошибки)
- В коде я установил свойство, привязанное к текстовому полю, на 0
- Форма все еще отображает 1 в красном текстовом поле
ПРИМЕР КОДА
Я подготовил пример, демонстрирующий проблему, который можно загрузить здесь.
Я опубликую часть кода здесь, если вы хотите больше, дайте мне знать.
ValidationTestControl's XAML
<UserControl x:Class="WPFTestProject.ValidationTestControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:v="clr-namespace:WPFTestProject"
x:Name="ValidationTest"
Height="50" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="Type 'Banana' here: "></TextBlock>
<TextBox MinWidth="100">
<TextBox.Text>
<Binding ElementName="ValidationTest" Path="Text" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" ValidatesOnDataErrors="True" ValidatesOnExceptions="True">
<Binding.ValidationRules>
<v:NotBananaValidationRule>
<v:NotBananaValidationRule.NotWhatBinding>
<v:NotBananaBinding x:Name="NotBananaValidationBinding"></v:NotBananaBinding>
</v:NotBananaValidationRule.NotWhatBinding>
</v:NotBananaValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBlock Text=" (the text will give error when = 'Banana')"></TextBlock>
</StackPanel>
</Grid>
ValidationTestControls Code Behind
(да, я знаю не очень MVVMно я чувствовал, что это нормально для этого автономного элемента управления)
public partial class ValidationTestControl : UserControl
{
public ValidationTestControl()
{
InitializeComponent();
Banana = "Banana";
Binding BananaBinding = new Binding("Banana");
BananaBinding.Source = this;
NotBananaValidationBinding.SetBinding(NotBananaBinding.NotWhatProperty, BananaBinding);
}
public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ValidationTestControl), new PropertyMetadata());
public static DependencyProperty BananaProperty = DependencyProperty.Register("Banana", typeof(string), typeof(ValidationTestControl), new PropertyMetadata());
public string Text
{
get
{
return (string)GetValue(TextProperty);
}
set
{
SetValue(TextProperty, value);
}
}
public string Banana
{
get
{
return (string)GetValue(BananaProperty);
}
set
{
SetValue(BananaProperty, value);
}
}
}
ValidationRule и FrameWorkElement, созданные для привязки
public class NotBananaValidationRule:ValidationRule
{
private NotBananaBinding _notWhatBinding;
public NotBananaBinding NotWhatBinding
{
get { return _notWhatBinding; }
set { _notWhatBinding = value; }
}
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
string what = value.ToString();
if(what == _notWhatBinding.NotWhat||string.IsNullOrEmpty(what))
return new ValidationResult(false,
"Please enter a string that is not " + _notWhatBinding.NotWhat);
else
return new ValidationResult(true, null);
}
}
public class NotBananaBinding : FrameworkElement
{
public static readonly DependencyProperty NotWhatProperty = DependencyProperty.Register(
"NotWhat", typeof(string), typeof(NotBananaBinding), new UIPropertyMetadata());
public string NotWhat
{
get { return (string)GetValue(NotWhatProperty); }
set { SetValue(NotWhatProperty, value); }
}
public NotBananaBinding() { }
}
По сути, этот код проверяет, еслиВы ввели «Банан», а затем возвращает ошибку проверки.Элемент управления предоставляет свойства зависимостей, потому что я хочу иметь возможность привязываться к ним при использовании элемента управления.FrameworkElement
NotBananaBinding позволяет мне создавать свойства зависимостей (потому что это DependencyObject
, поэтому я могу связывать вещи для проверки. ValidationRule имеет свойство NotBananaBinding , в котором хранится свойство зависимостии использует его в методе validate.
Я знаю, что мои имена свойств довольно дурацкие, извините. Дело в том, что пример хорошо справляется с отображением ошибки. В спешке приведу пример, который я не сделал.Перечислите переменные очень хорошо. Если вы нашли код дрянной , пожалуйста, скачайте образец здесь.
ЧТО Я ТАК ВЫБИРАЛFAR
В основном эта проблема, по-видимому, вызвана тем фактом, что я фактически не изменяю значение .
Даже если я вызову OnPropertyChanged для свойства,поскольку значение не отличается, оно не пытается переоценить валидацию.
Я, очевидно, могу изменить значение на произвольное допустимое значение, а затем изменить его на то, что я хочуэто будет, и это будет работать, но я надеялся, что есть какой-то способ получить подтверждение вызова вручную, переоценить значение, а затем изменить его и т. д. Смена его и возвращение довольно грязная.
ЗАКЛЮЧЕНИЕ
Я делаю что-то не так (возможно, что-то в том, как я реализовал проверку и привязку из поста Джоша Смита)
Это просто ошибка ac #, илитакое поведение предназначено?Если так, то почему?
Существуют ли элегантные способы исправить это?
u_u