UserControl属性的触发器从后面的代码更改

时间:2017-09-07 08:08:11

标签: c# wpf triggers user-controls

我正在写一个UserControl TextBox,当它里面的文字不是有效数字时会改变颜色。

这是类声明:

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

}

xaml只是一个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>

我试图在属性IsValid错误时尝试更改边框:

<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>

如果我将触发器从False更改为True,控件上会出现红色边框,如果我将IsValid绑定到例如CheckBox&#39; {{ 1}}属性也有效。唯一不会改变边界的是改变代码背后的价值。可以看出,我已尝试使用INorifyPropertyChanged界面,因为这是本页中许多问题的答案。但是,IsChecked事件的值始终为null,并且在TextBox中写入字母时没有任何反应。

1 个答案:

答案 0 :(得分:2)

IsValid是一个依赖属性,应该有一个CLR包装器:

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);
    }
}

您不必实现INotifyPropertyChanged接口来提出依赖项属性的更改通知。