Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Fix PasswordBoxBindingBehavior and IsWaitingForData #2355

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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