Skip to content

Commit

Permalink
Merge pull request #2355 from MahApps/PasswordBoxBindingBehavior-And-…
Browse files Browse the repository at this point in the history
…PasswordBox-TextBox-Style-Fixes

[WIP] Fix PasswordBoxBindingBehavior and IsWaitingForData
  • Loading branch information
punker76 committed Feb 18, 2016
2 parents e9c7e9d + 97dbab2 commit 1a91bfe
Show file tree
Hide file tree
Showing 11 changed files with 465 additions and 358 deletions.
99 changes: 68 additions & 31 deletions MahApps.Metro/Behaviours/PasswordBoxBindingBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,73 +3,110 @@
// For more information see : http://wpfsmartlibrary.codeplex.com/
// (by DotNetMastermind)
// --------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Threading;

namespace MahApps.Metro.Behaviours
{
using System.ComponentModel;

public class PasswordBoxBindingBehavior : Behavior<PasswordBox>
{
#region Fields

private static bool IsUpdating;

#endregion

#region DependencyProperty - Password ("string")
/// <summary>
/// Gets or sets the bindable Password property on the PasswordBox control. This is a dependency property.
/// </summary>
public static readonly DependencyProperty PasswordProperty
= DependencyProperty.RegisterAttached("Password", typeof(string),
typeof(PasswordBoxBindingBehavior),
new FrameworkPropertyMetadata(string.Empty, new PropertyChangedCallback(OnPasswordPropertyChanged)));

[Category(AppName.MahApps)]
public static string GetPassword(DependencyObject dpo)
{
return (string)dpo.GetValue(PasswordProperty);
}

public static void SetPassword(DependencyObject dpo, string value)
{
dpo.SetValue(PasswordProperty, value);
}

/// <summary>
/// Gets or sets the bindable Password property on the PasswordBox control. This is a dependency property.
/// </summary>
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.RegisterAttached("Password", typeof(string),
typeof(PasswordBoxBindingBehavior),
new FrameworkPropertyMetadata(String.Empty,
new PropertyChangedCallback(OnPasswordPropertyChanged)));
/// <summary>
/// Handles changes to the 'Password' attached property.
/// Handles changes to the 'Password' attached property.
/// </summary>
private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
PasswordBox targetPasswordBox = sender as PasswordBox;
var targetPasswordBox = sender as PasswordBox;
if (targetPasswordBox != null)
{
targetPasswordBox.PasswordChanged -= PasswordBox_PasswordChanged;
if (IsUpdating == false)
targetPasswordBox.PasswordChanged -= PasswordBoxPasswordChanged;
if (!GetIsChanging(targetPasswordBox))
{
targetPasswordBox.Password = (string)e.NewValue;
}
targetPasswordBox.PasswordChanged += PasswordBox_PasswordChanged;
targetPasswordBox.PasswordChanged += PasswordBoxPasswordChanged;
}
}

/// <summary>
/// Handle the 'PasswordChanged'-event on the PasswordBox
/// Handle the 'PasswordChanged'-event on the PasswordBox
/// </summary>
private static void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
private static void PasswordBoxPasswordChanged(object sender, RoutedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
IsUpdating = true;
var passwordBox = (PasswordBox)sender;
SetIsChanging(passwordBox, true);
SetPassword(passwordBox, passwordBox.Password);
IsUpdating = false;
SetIsChanging(passwordBox, false);
}

#endregion
/// <summary>
/// Called after the behavior is attached to an AssociatedObject.
/// </summary>
/// <remarks>
/// Override this to hook up functionality to the AssociatedObject.
/// </remarks>
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.PasswordChanged += PasswordBoxPasswordChanged;
this.Dispatcher.BeginInvoke(DispatcherPriority.Loaded,
new Action(() => {
if (this.AssociatedObject != null)
{
SetPassword(this.AssociatedObject, this.AssociatedObject.Password);
}
}));
}

/// <summary>
/// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.
/// </summary>
/// <remarks>
/// Override this to unhook functionality from the AssociatedObject.
/// </remarks>
protected override void OnDetaching()
{
this.AssociatedObject.PasswordChanged -= PasswordBoxPasswordChanged;
base.OnDetaching();
}

private static readonly DependencyProperty IsChangingProperty
= DependencyProperty.RegisterAttached("IsChanging",
typeof(bool),
typeof(PasswordBoxBindingBehavior),
new UIPropertyMetadata(false));

private static bool GetIsChanging(DependencyObject obj)
{
return (bool)obj.GetValue(IsChangingProperty);
}

private static void SetIsChanging(DependencyObject obj, bool value)
{
obj.SetValue(IsChangingProperty, value);
}
}
}
138 changes: 89 additions & 49 deletions MahApps.Metro/Behaviours/StylizedBehaviors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@
namespace MahApps.Metro.Behaviours
{
using System.ComponentModel;
using System.Windows.Threading;

public class StylizedBehaviors
{
private static readonly DependencyProperty OriginalBehaviorProperty = DependencyProperty.RegisterAttached(@"OriginalBehaviorInternal", typeof(Behavior), typeof(StylizedBehaviors), new UIPropertyMetadata(null));

public static readonly DependencyProperty BehaviorsProperty = DependencyProperty.RegisterAttached(
@"Behaviors",
typeof(StylizedBehaviorCollection),
typeof(StylizedBehaviors),
new FrameworkPropertyMetadata(null, OnPropertyChanged));
public static readonly DependencyProperty BehaviorsProperty
= DependencyProperty.RegisterAttached("Behaviors",
typeof(StylizedBehaviorCollection),
typeof(StylizedBehaviors),
new FrameworkPropertyMetadata(null, OnPropertyChanged));

[Category(AppName.MahApps)]
public static StylizedBehaviorCollection GetBehaviors(DependencyObject uie)
Expand All @@ -26,66 +25,30 @@ public static void SetBehaviors(DependencyObject uie, StylizedBehaviorCollection
uie.SetValue(BehaviorsProperty, value);
}

private static Behavior GetOriginalBehavior(DependencyObject obj)
{
return obj.GetValue(OriginalBehaviorProperty) as Behavior;
}

private static int GetIndexOf(BehaviorCollection itemBehaviors, Behavior behavior)
{
int index = -1;

Behavior orignalBehavior = GetOriginalBehavior(behavior);

for (int i = 0; i < itemBehaviors.Count; i++)
{
Behavior currentBehavior = itemBehaviors[i];

if (currentBehavior == behavior
|| currentBehavior == orignalBehavior)
{
index = i;
break;
}

Behavior currentOrignalBehavior = GetOriginalBehavior(currentBehavior);

if (currentOrignalBehavior == behavior
|| currentOrignalBehavior == orignalBehavior)
{
index = i;
break;
}
}

return index;
}

private static void OnPropertyChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs e)
{
var uie = dpo as UIElement;

var uie = dpo as FrameworkElement;
if (uie == null)
{
return;
}

BehaviorCollection itemBehaviors = Interaction.GetBehaviors(uie);

var newBehaviors = e.NewValue as StylizedBehaviorCollection;
var oldBehaviors = e.OldValue as StylizedBehaviorCollection;

if (newBehaviors == oldBehaviors)
{
return;
}

BehaviorCollection itemBehaviors = Interaction.GetBehaviors(uie);

uie.Unloaded -= FrameworkElementUnloaded;

if (oldBehaviors != null)
{
foreach (var behavior in oldBehaviors)
{
int index = GetIndexOf(itemBehaviors, behavior);

if (index >= 0)
{
itemBehaviors.RemoveAt(index);
Expand All @@ -98,7 +61,6 @@ private static void OnPropertyChanged(DependencyObject dpo, DependencyPropertyCh
foreach (var behavior in newBehaviors)
{
int index = GetIndexOf(itemBehaviors, behavior);

if (index < 0)
{
var clone = (Behavior)behavior.Clone();
Expand All @@ -107,6 +69,84 @@ private static void OnPropertyChanged(DependencyObject dpo, DependencyPropertyCh
}
}
}

if (itemBehaviors.Count > 0)
{
uie.Unloaded += FrameworkElementUnloaded;
}
uie.Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
}

private static void Dispatcher_ShutdownStarted(object sender, System.EventArgs e)
{
var s = "";
}

private static void FrameworkElementUnloaded(object sender, RoutedEventArgs e)
{
// BehaviorCollection doesn't call Detach, so we do this
var uie = sender as FrameworkElement;
if (uie == null)
{
return;
}
BehaviorCollection itemBehaviors = Interaction.GetBehaviors(uie);
foreach (var behavior in itemBehaviors) {
behavior.Detach();
}
uie.Loaded += FrameworkElementLoaded;
}

private static void FrameworkElementLoaded(object sender, RoutedEventArgs e)
{
var uie = sender as FrameworkElement;
if (uie == null)
{
return;
}
uie.Loaded -= FrameworkElementLoaded;
BehaviorCollection itemBehaviors = Interaction.GetBehaviors(uie);
foreach (var behavior in itemBehaviors)
{
behavior.Attach(uie);
}
}

private static int GetIndexOf(BehaviorCollection itemBehaviors, Behavior behavior)
{
int index = -1;

Behavior orignalBehavior = GetOriginalBehavior(behavior);

for (int i = 0; i < itemBehaviors.Count; i++)
{
Behavior currentBehavior = itemBehaviors[i];
if (currentBehavior == behavior || currentBehavior == orignalBehavior)
{
index = i;
break;
}

Behavior currentOrignalBehavior = GetOriginalBehavior(currentBehavior);
if (currentOrignalBehavior == behavior || currentOrignalBehavior == orignalBehavior)
{
index = i;
break;
}
}

return index;
}

private static readonly DependencyProperty OriginalBehaviorProperty
= DependencyProperty.RegisterAttached("OriginalBehaviorInternal",
typeof(Behavior),
typeof(StylizedBehaviors),
new UIPropertyMetadata(null));

private static Behavior GetOriginalBehavior(DependencyObject obj)
{
return obj.GetValue(OriginalBehaviorProperty) as Behavior;
}

private static void SetOriginalBehavior(DependencyObject obj, Behavior value)
Expand Down
5 changes: 5 additions & 0 deletions MahApps.Metro/MahApps.Metro.NET45.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,11 @@
<SubType>Designer</SubType>
<DependentUpon>Controls.xaml</DependentUpon>
</Page>
<Page Include="Styles\Controls.Shadows.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<DependentUpon>Controls.xaml</DependentUpon>
</Page>
<Page Include="Styles\Controls.Buttons.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
Expand Down
5 changes: 5 additions & 0 deletions MahApps.Metro/MahApps.Metro.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,11 @@
<SubType>Designer</SubType>
<DependentUpon>Controls.xaml</DependentUpon>
</Page>
<Page Include="Styles\Controls.Shadows.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<DependentUpon>Controls.xaml</DependentUpon>
</Page>
<Page Include="Styles\Controls.Buttons.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
Expand Down
2 changes: 0 additions & 2 deletions MahApps.Metro/Styles/Colors.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@
<GradientStop Color="{DynamicResource AccentColor3}" Offset="1"/>
</LinearGradientBrush>

<DropShadowEffect x:Key="DropShadowBrush" Direction="330" Opacity="0.3" ShadowDepth="0" BlurRadius="6"/>

<SolidColorBrush x:Key="WindowBackgroundBrush" Color="{DynamicResource WhiteColor}" />
<SolidColorBrush x:Key="SeperatorBrush" Color="#FFC4C4C5"/>

Expand Down
Loading

0 comments on commit 1a91bfe

Please sign in to comment.