I'm writing a UserControl TextBox that will change color when the text inside it is not a valid number.
This is the class declaration:
public partial class ValidatedNumberBox : UserControl, INotifyPropertyChanged
{
public bool IsValid { get; set; }
public static readonly DependencyProperty IsValidProperty = DependencyProperty.RegisterAttached(
nameof(IsValid), typeof(bool), typeof(ValidatedNumberBox), new PropertyMetadata(true));
public ValidatedNumberBox()
{
InitializeComponent();
IsValid = CheckValidity();
}
private void PART_TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
IsValid = CheckValidity();
OnPropertyChanged(nameof(IsValid));
TextChanged?.Invoke(sender, e);
}
private bool CheckValidity()
{
return !PART_TextBox.Text.Any(char.IsLetter);
}
#region INotify
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
The xaml is simply a TextBox:
<UserControl x:Class="fisWPF.Controls.ValidatedNumberBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<TextBox Name="PART_TextBox" TextChanged="PART_TextBox_OnTextChanged" />
</Grid>
I'm trying to get a border to change when the property IsValid
is false like so:
<Style TargetType="{x:Type Controls:ValidatedNumberBox}">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:ValidatedNumberBox}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsValid" Value="False">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="20"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If I change the trigger from False
to True
the red border appears on the control, and if I bind IsValid
to, for instance, a CheckBox's IsChecked
property it works too. The only thing that won't change the border is changing the value in code behind. As can be seen, I've tried using the INorifyPropertyChanged interface as is the answer to many questions in this page. However, the value of the PropertyChanged
event is always null and nothing happens when I write letters in the TextBox.
IsValid
is a dependency property that is supposed to have a CLR wrapper:
public partial class ValidatedNumberBox : UserControl
{
public static readonly DependencyProperty IsValidProperty = DependencyProperty.RegisterAttached(
nameof(IsValid), typeof(bool), typeof(ValidatedNumberBox), new PropertyMetadata(true));
// .NET property wrapper
public bool IsValid
{
get { return (bool)GetValue(IsValidProperty); }
set { SetValue(IsValidProperty, value); }
}
public ValidatedNumberBox()
{
InitializeComponent();
IsValid = CheckValidity();
}
private void PART_TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
IsValid = CheckValidity();
TextChanged?.Invoke(sender, e);
}
private bool CheckValidity()
{
return !PART_TextBox.Text.Any(char.IsLetter);
}
}
You don't have to implement the INotifyPropertyChanged
interface to raise change notifications for dependency properties.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.