I have some code that works intermittently and I can't understand why (worked perfectly until today morning when windows automatically installed some updates, but none related to .NET 4 - version used in my project).
My password box ...
<PasswordBox x:Name="TboxPassword" Grid.Row="1" Grid.Column="0"
controls:TextboxHelper.Watermark="Password ..."
controls:TextboxHelper.ClearTextButton="True"
Margin="10, 10, 0, 0">
<i:Interaction.Behaviors>
<misc:PasswordBoxBehavior Password="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/>
</i:Interaction.Behaviors>
</PasswordBox>
My behavior:
public class PasswordBoxBehavior : Behavior<PasswordBox>
{
#region Fields
private readonly object _tryToExecuteActionSyncObject = new object();
private bool _isUpdating;
#endregion
#region Properties
public string Password
{
get { return (string)GetValue(PasswordProperty); }
set { SetValue(PasswordProperty, value); }
}
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.Register("Password", typeof(string), typeof(PasswordBoxBehavior),
new PropertyMetadata(string.Empty, OnPasswordPropertyChanged));
#endregion
#region Methods
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.PasswordChanged += OnAssociatedObjectPasswordChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.PasswordChanged -= OnAssociatedObjectPasswordChanged;
}
private void OnAssociatedObjectPasswordChanged(object sender, RoutedEventArgs e)
{
TryToExecuteAction(() => Password = AssociatedObject == null
? string.Empty
: AssociatedObject.Password);
}
private static void OnPasswordPropertyChanged
(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
PasswordBoxBehavior passwordBoxBehavior;
if (sender == null
|| (passwordBoxBehavior = sender as PasswordBoxBehavior) == null
|| passwordBoxBehavior.AssociatedObject == null)
{
return;
}
passwordBoxBehavior.TryToExecuteAction
(() => passwordBoxBehavior.AssociatedObject.Password =
(e.NewValue == null
? string.Empty
: (string) e.NewValue));
}
private void TryToExecuteAction(Action actionToExecute)
{
bool continueExecution;
lock (_tryToExecuteActionSyncObject)
{
continueExecution = _isUpdating == false;
_isUpdating = true;
}
if (continueExecution == false)
{
return;
}
try
{
if (actionToExecute != null)
{
actionToExecute();
}
}
finally
{
lock (_tryToExecuteActionSyncObject)
{
_isUpdating = false;
}
}
}
#endregion
}
I get 0 (zero) compilation errors. When running the application, 90% of the time I'm getting a runtime exception stating that:
{"Cannot add instance of type 'PasswordBoxBehavior' to a collection of type 'BehaviorCollection'. Only items of type 'T' are allowed."}
Debugger stops at the tag Interaction.Behaviors
Please keep in mind that I never received this error until today. Now I receive it even after I revert everything I done today.
Please advise .. :D
PS: I just commented out all the code from inside the behavior. Also removed the Password binding. Still doesn't work :(
PPS: If I close Visual Studio (2012), delete my bin folder, open VS, open project, rebuild all, the application WORKS until the first change to the code.