Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF TextBox setting red border on Validation

Tags:

c#

validation

wpf

I'm trying to make textbox's border red when it's empty. Here's my xaml:

     <TextBox  Style="{StaticResource TextBoxEmptyError}" Name="tbFilename" Grid.Column="1" >
         <Binding Path="Text" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
            <Binding.ValidationRules>
                <local:EmptyRule />
            </Binding.ValidationRules>
        </Binding>
    </TextBox>

style i'm trying to set:

        <Style x:Key="TextBoxEmptyError" TargetType="{x:Type TextBox}">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="True">
                    <Setter Property="BorderThickness" Value="2" />
                    <Setter Property="BorderBrush" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>

EmptyRule:

public class EmptyRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            if (string.IsNullOrEmpty(value as string))
                return new ValidationResult(false, null);
            else
                return new ValidationResult(true, null);

        }
    }

In debugger it looks like Validation method isn't used at all. What am I doing wrong?

like image 899
Piotr L Avatar asked May 11 '16 02:05

Piotr L


Video Answer


1 Answers

I cannot see where you set DataContext between XAML and viewModel.

DataContext is a way to know where XAML(View, your Window) can get data from.

For example, you have model class:

internal class SomeUser
{        
    private string _name;
    private string _address;

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
        }
    }

    public string Address
    {
        get { return _address; }
        set { _address = value; }
    }
}

Then you should set DataContext to your Window. For example, in code-behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new SomeUser();       
    }
}

then XAML should looks like this:

<Grid>
  <Grid.Resources> 
     <Style x:Key="CustomTextBoxTextStyle" TargetType="TextBox">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <Border x:Name="bg" BorderBrush="#FF825E5E" BorderThickness="1">
                            <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                        <ControlTemplate.Triggers>

                            <Trigger Property="Validation.HasError" Value="True">
                                <Trigger.Setters>
                                    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors)[0].ErrorContent}"/>                                        
                                    <Setter Property="BorderThickness" TargetName="bg" Value="2"/>
                                    <Setter Property="BorderBrush" TargetName="bg" Value="Red"/>
                                </Trigger.Setters>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Grid.Resources>
</Grid>

<TextBox Style="{StaticResource CustomTextBoxTextStyle}" Height="23" Name="textBox1" Margin="25">
            <Validation.ErrorTemplate>
                <ControlTemplate>
                    <DockPanel>
                        <TextBlock Foreground="Red" DockPanel.Dock="Right">!</TextBlock>
                        <AdornedElementPlaceholder x:Name="ErrorAdorner"
    ></AdornedElementPlaceholder>
                    </DockPanel>
                </ControlTemplate>
            </Validation.ErrorTemplate>

            <TextBox.Text>
                <Binding Path="Name" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <local:NameValidator></local:NameValidator>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
</TextBox>
like image 95
StepUp Avatar answered Oct 05 '22 23:10

StepUp