Also, behaviors may provide properties and events that you can set or bind in Xaml.
public class ValidationBehavior : Behavior<TextBox> {
public static readonly DependencyProperty ValidForegroundProperty =
DependencyProperty.Register("ValidForeground", typeof(Brush), typeof(ValidationBehavior),
new PropertyMetadata(new SolidColorBrush(Colors.Black), (d, e) => ((ValidationBehavior)d).Update()));
public static readonly DependencyProperty InvalidForegroundProperty =
DependencyProperty.Register("InvalidForeground", typeof(Brush), typeof(ValidationBehavior),
new PropertyMetadata(new SolidColorBrush(Colors.Red), (d,e) => ((ValidationBehavior)d).Update()));
public static readonly DependencyProperty InvalidValueProperty =
DependencyProperty.Register("InvalidValue", typeof(string), typeof(ValidationBehavior),
new PropertyMetadata(string.Empty, (d, e) => ((ValidationBehavior)d).Update()));
public Brush ValidForeground {
get { return (Brush)GetValue(ValidForegroundProperty); }
set { SetValue(ValidForegroundProperty, value); }
}
public Brush InvalidForeground {
get { return (Brush)GetValue(InvalidForegroundProperty); }
set { SetValue(InvalidForegroundProperty, value); }
}
public string InvalidValue {
get { return (string)GetValue(InvalidValueProperty); }
set { SetValue(InvalidValueProperty, value); }
}
protected override void OnAttached() {
base.OnAttached();
AssociatedObject.TextChanged += OnAssociatedObjectTextChanged;
Update();
}
protected override void OnDetaching() {
AssociatedObject.TextChanged -= OnAssociatedObjectTextChanged;
base.OnDetaching();
}
void OnAssociatedObjectTextChanged(object sender, TextChangedEventArgs e) {
Update();
}
void Update() {
if(AssociatedObject == null) return;
if(AssociatedObject.Text == InvalidValue)
AssociatedObject.Foreground = InvalidForeground;
else AssociatedObject.Foreground = ValidForeground;
}
}
Public Class ValidationBehavior
Inherits Behavior(Of TextBox)
Public Shared ReadOnly ValidForegroundProperty As DependencyProperty = DependencyProperty.Register("ValidForeground", GetType(Brush), GetType(ValidationBehavior), New PropertyMetadata(New SolidColorBrush(Colors.Black), Sub(d, e) CType(d, ValidationBehavior).Update()))
Public Shared ReadOnly InvalidForegroundProperty As DependencyProperty = DependencyProperty.Register("InvalidForeground", GetType(Brush), GetType(ValidationBehavior), New PropertyMetadata(New SolidColorBrush(Colors.Red), Sub(d,e) CType(d, ValidationBehavior).Update()))
Public Shared ReadOnly InvalidValueProperty As DependencyProperty = DependencyProperty.Register("InvalidValue", GetType(String), GetType(ValidationBehavior), New PropertyMetadata(String.Empty, Sub(d, e) CType(d, ValidationBehavior).Update()))
Public Property ValidForeground() As Brush
Get
Return CType(GetValue(ValidForegroundProperty), Brush)
End Get
Set(ByVal value As Brush)
SetValue(ValidForegroundProperty, value)
End Set
End Property
Public Property InvalidForeground() As Brush
Get
Return CType(GetValue(InvalidForegroundProperty), Brush)
End Get
Set(ByVal value As Brush)
SetValue(InvalidForegroundProperty, value)
End Set
End Property
Public Property InvalidValue() As String
Get
Return CStr(GetValue(InvalidValueProperty))
End Get
Set(ByVal value As String)
SetValue(InvalidValueProperty, value)
End Set
End Property
Protected Overrides Sub OnAttached()
MyBase.OnAttached()
AddHandler AssociatedObject.TextChanged, AddressOf OnAssociatedObjectTextChanged
Update()
End Sub
Protected Overrides Sub OnDetaching()
RemoveHandler AssociatedObject.TextChanged, AddressOf OnAssociatedObjectTextChanged
MyBase.OnDetaching()
End Sub
Private Sub OnAssociatedObjectTextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
Update()
End Sub
Private Sub Update()
If AssociatedObject Is Nothing Then
Return
End If
If AssociatedObject.Text = InvalidValue Then
AssociatedObject.Foreground = InvalidForeground
Else
AssociatedObject.Foreground = ValidForeground
End If
End Sub
End Class
The below example demonstrates a more complex example of how to create a custom Behavior.
Imports DevExpress.Mvvm.DataAnnotations
Imports System.Windows.Media
Namespace Example.ViewModel
<POCOViewModel> _
Public Class MainViewModel
Public Overridable Property InvalidValue() As String
Public Overridable Property ValidBrush() As Brush
Public Overridable Property InvalidBrush() As Brush
Public Sub SetRedValidBrush()
ValidBrush = New SolidColorBrush(Colors.Red)
End Sub
Public Sub SetBlueValidBrush()
ValidBrush = New SolidColorBrush(Colors.Blue)
End Sub
Public Sub SetBlackValidBrush()
ValidBrush = New SolidColorBrush(Colors.Black)
End Sub
Public Sub SetRedInvalidBrush()
InvalidBrush = New SolidColorBrush(Colors.Red)
End Sub
Public Sub SetBlueInvalidBrush()
InvalidBrush = New SolidColorBrush(Colors.Blue)
End Sub
Public Sub SetBlackInvalidBrush()
InvalidBrush = New SolidColorBrush(Colors.Black)
End Sub
Public Sub New()
InvalidValue = "Error"
SetBlackValidBrush()
SetRedInvalidBrush()
End Sub
End Class
End Namespace
Imports System.Windows
Namespace Example
Partial Public Class MainWindow
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
End Class
End Namespace
Imports System.Windows.Controls
Namespace Example.View
Partial Public Class MainView
Inherits UserControl
Public Sub New()
InitializeComponent()
End Sub
End Class
End Namespace
Imports DevExpress.Mvvm.UI.Interactivity
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Namespace Example.Behaviors
Public Class ValidationBehavior
Inherits Behavior(Of TextBox)
Public Shared ReadOnly ValidForegroundProperty As DependencyProperty = DependencyProperty.Register("ValidForeground", GetType(Brush), GetType(ValidationBehavior), New PropertyMetadata(New SolidColorBrush(Colors.Black), Sub(d, e) CType(d, ValidationBehavior).Update()))
Public Shared ReadOnly InvalidForegroundProperty As DependencyProperty = DependencyProperty.Register("InvalidForeground", GetType(Brush), GetType(ValidationBehavior), New PropertyMetadata(New SolidColorBrush(Colors.Red), Sub(d,e) CType(d, ValidationBehavior).Update()))
Public Shared ReadOnly InvalidValueProperty As DependencyProperty = DependencyProperty.Register("InvalidValue", GetType(String), GetType(ValidationBehavior), New PropertyMetadata(String.Empty, Sub(d, e) CType(d, ValidationBehavior).Update()))
Public Property ValidForeground() As Brush
Get
Return CType(GetValue(ValidForegroundProperty), Brush)
End Get
Set(ByVal value As Brush)
SetValue(ValidForegroundProperty, value)
End Set
End Property
Public Property InvalidForeground() As Brush
Get
Return CType(GetValue(InvalidForegroundProperty), Brush)
End Get
Set(ByVal value As Brush)
SetValue(InvalidForegroundProperty, value)
End Set
End Property
Public Property InvalidValue() As String
Get
Return CStr(GetValue(InvalidValueProperty))
End Get
Set(ByVal value As String)
SetValue(InvalidValueProperty, value)
End Set
End Property
Protected Overrides Sub OnAttached()
MyBase.OnAttached()
AddHandler AssociatedObject.TextChanged, AddressOf OnAssociatedObjectTextChanged
Update()
End Sub
Protected Overrides Sub OnDetaching()
RemoveHandler AssociatedObject.TextChanged, AddressOf OnAssociatedObjectTextChanged
MyBase.OnDetaching()
End Sub
Private Sub OnAssociatedObjectTextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
Update()
End Sub
Private Sub Update()
If AssociatedObject Is Nothing Then
Return
End If
If AssociatedObject.Text = InvalidValue Then
AssociatedObject.Foreground = InvalidForeground
Else
AssociatedObject.Foreground = ValidForeground
End If
End Sub
End Class
End Namespace
Imports System.Windows
Namespace Example
Partial Public Class App
Inherits Application
Public Sub New()
AddHandler Startup, AddressOf OnStartup
#If SILVERLIGHT Then
InitializeComponent()
#End If
End Sub
Private Overloads Sub OnStartup(ByVal sender As Object, ByVal e As StartupEventArgs)
#If SILVERLIGHT Then
Me.RootVisual = New MainPage()
#Else
MainWindow = New MainWindow()
MainWindow.Show()
#End If
End Sub
End Class
End Namespace
<UserControl x:Class="Example.View.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModel="clr-namespace:Example.ViewModel"
xmlns:Behaviors="clr-namespace:Example.Behaviors"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="600"
DataContext="{dxmvvm:ViewModelSource Type=ViewModel:MainViewModel}">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="InputBox: " VerticalAlignment="Center" Margin="5"/>
<TextBox Text="Error" Margin="5" Width="80">
<dxmvvm:Interaction.Behaviors>
<Behaviors:ValidationBehavior ValidForeground="{Binding ValidBrush}"
InvalidForeground="{Binding InvalidBrush}"
InvalidValue="{Binding InvalidValue}"/>
</dxmvvm:Interaction.Behaviors>
</TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="InvalidValue: " VerticalAlignment="Center" Margin="5"/>
<TextBox Text="{Binding InvalidValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="5" Width="80"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="ValidBrush" VerticalAlignment="Center" Margin="5"/>
<Button Command="{Binding SetRedValidBrushCommand}">
<Border Width="20" Height="20" Background="Red" Margin="5" VerticalAlignment="Center"/>
</Button>
<Button Command="{Binding SetBlueValidBrushCommand}">
<Border Width="20" Height="20" Background="Blue" Margin="5" VerticalAlignment="Center"/>
</Button>
<Button Command="{Binding SetBlackValidBrushCommand}">
<Border Width="20" Height="20" Background="Black" Margin="5" VerticalAlignment="Center"/>
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="InvalidBrush" VerticalAlignment="Center" Margin="5"/>
<Button Command="{Binding SetRedInvalidBrushCommand}">
<Border Width="20" Height="20" Background="Red" Margin="5" VerticalAlignment="Center"/>
</Button>
<Button Command="{Binding SetBlueInvalidBrushCommand}">
<Border Width="20" Height="20" Background="Blue" Margin="5" VerticalAlignment="Center"/>
</Button>
<Button Command="{Binding SetBlackInvalidBrushCommand}">
<Border Width="20" Height="20" Background="Black" Margin="5" VerticalAlignment="Center"/>
</Button>
</StackPanel>
</StackPanel>
</Grid>
</UserControl>
<Application x:Class="Example.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
</Application.Resources>
</Application>
<Window x:Class="Example.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:View="clr-namespace:Example.View"
Title="MainWindow" Height="600" Width="800">
<Grid>
<View:MainView/>
</Grid>
</Window>
using DevExpress.Mvvm.DataAnnotations;
using System.Windows.Media;
namespace Example.ViewModel {
[POCOViewModel]
public class MainViewModel {
public virtual string InvalidValue { get; set; }
public virtual Brush ValidBrush { get; set; }
public virtual Brush InvalidBrush { get; set; }
public void SetRedValidBrush() {
ValidBrush = new SolidColorBrush(Colors.Red);
}
public void SetBlueValidBrush() {
ValidBrush = new SolidColorBrush(Colors.Blue);
}
public void SetBlackValidBrush() {
ValidBrush = new SolidColorBrush(Colors.Black);
}
public void SetRedInvalidBrush() {
InvalidBrush = new SolidColorBrush(Colors.Red);
}
public void SetBlueInvalidBrush() {
InvalidBrush = new SolidColorBrush(Colors.Blue);
}
public void SetBlackInvalidBrush() {
InvalidBrush = new SolidColorBrush(Colors.Black);
}
public MainViewModel() {
InvalidValue = "Error";
SetBlackValidBrush();
SetRedInvalidBrush();
}
}
}
using System.Windows.Controls;
namespace Example.View {
public partial class MainView : UserControl {
public MainView() {
InitializeComponent();
}
}
}
using System.Windows;
namespace Example {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
}
}
using DevExpress.Mvvm.UI.Interactivity;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Example.Behaviors {
public class ValidationBehavior : Behavior<TextBox> {
public static readonly DependencyProperty ValidForegroundProperty =
DependencyProperty.Register("ValidForeground", typeof(Brush), typeof(ValidationBehavior),
new PropertyMetadata(new SolidColorBrush(Colors.Black), (d, e) => ((ValidationBehavior)d).Update()));
public static readonly DependencyProperty InvalidForegroundProperty =
DependencyProperty.Register("InvalidForeground", typeof(Brush), typeof(ValidationBehavior),
new PropertyMetadata(new SolidColorBrush(Colors.Red), (d,e) => ((ValidationBehavior)d).Update()));
public static readonly DependencyProperty InvalidValueProperty =
DependencyProperty.Register("InvalidValue", typeof(string), typeof(ValidationBehavior),
new PropertyMetadata(string.Empty, (d, e) => ((ValidationBehavior)d).Update()));
public Brush ValidForeground {
get { return (Brush)GetValue(ValidForegroundProperty); }
set { SetValue(ValidForegroundProperty, value); }
}
public Brush InvalidForeground {
get { return (Brush)GetValue(InvalidForegroundProperty); }
set { SetValue(InvalidForegroundProperty, value); }
}
public string InvalidValue {
get { return (string)GetValue(InvalidValueProperty); }
set { SetValue(InvalidValueProperty, value); }
}
protected override void OnAttached() {
base.OnAttached();
AssociatedObject.TextChanged += OnAssociatedObjectTextChanged;
Update();
}
protected override void OnDetaching() {
AssociatedObject.TextChanged -= OnAssociatedObjectTextChanged;
base.OnDetaching();
}
void OnAssociatedObjectTextChanged(object sender, TextChangedEventArgs e) {
Update();
}
void Update() {
if(AssociatedObject == null) return;
if(AssociatedObject.Text == InvalidValue)
AssociatedObject.Foreground = InvalidForeground;
else AssociatedObject.Foreground = ValidForeground;
}
}
}