【发布时间】:2017-11-03 18:50:25
【问题描述】:
我有一个 WPF 应用程序并且正在使用 MVVM 模式。在我的一个用户控件上,我有两个 PasswordBox 来比较用户输入的密码。我正在尝试实现一个比较行为,其结果将确定是否应在 ViewModel 中启用或禁用提交按钮。我有点卡住了。
编辑: 这不是@Dbl 在评论中提到的重复问题。他的评论中提到的重复问题是关于如何比较两种 SecureString 数据类型。我的问题完全不同。它是关于如何在 XAML UserControl 中比较两个对象值——不管它们是否是 SecureString——而不破坏 MVVM 模式,其中附加到一个元素的行为需要知道该行为中另一个元素的值。此外,此行为需要能够访问元素的底层 ViewModel 并更新 ViewModel 中的 INPC 属性。
这是我的 XAML(为简洁起见,删除了相当多的元素):
<UserControl
x:Class="DynaProPOS.WPF.Views.AppUser"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behavior="clr-namespace:DynaProPOS.WPF.Behaviors"
xmlns:custProps="clr-namespace:DynaProPOS.WPF.CustomProperties"
prism:ViewModelLocator.AutoWireViewModel="True"
Background="{DynamicResource BackgroundBrush}">
<Border Width="750" Height="260" BorderBrush="White" BorderThickness="2">
<Grid x:Name="grid" KeyboardNavigation.TabNavigation="Cycle" Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" Width="Auto">
<PasswordBox TabIndex="3" Grid.Row="3" Grid.Column="1" Margin="2" x:Name="Password1" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<i:Interaction.Behaviors>
<behavior:PasswordBoxBindingBehavior Password="{Binding Password}" />
</i:Interaction.Behaviors>
</PasswordBox>
<PasswordBox TabIndex="4" Grid.Row="4" Grid.Column="1" Margin="2,18,2,4" x:Name="Password2" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<i:Interaction.Behaviors>
<behavior:ComparePasswordBehavior OriginalPassword="{Binding ElementName=Password1, Path=Password}"/>
</i:Interaction.Behaviors>
</PasswordBox>
<Grid Grid.Column="3" Grid.RowSpan="5" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="10*" />
<RowDefinition Height="90*" />
</Grid.RowDefinitions>
</Grid>
<syncfusion:ButtonAdv TabIndex="6" x:Name="RegisterButton" Grid.Row="5" Grid.Column="4" Margin="5" HorizontalAlignment="Right" Label="Submit" VerticalAlignment="Center" />
</Grid>
</Border>
这是我的 ViewModel(再次,为简洁起见,删除大量代码)。
public class AppUserViewModel : BindableBase
{
private bool isEnabled;
public AppUserViewModel(IAuthenticationService _authService)
{
authService = _authService;
RegisterCommand = new DelegateCommand( async () => await RegisterUserAsync() );
}
public bool IsEnabled
{
get { return isEnabled; }
set { SetProperty( ref isEnabled, value ); }
}
}
最后,这是我的 Behavior 类。
public class ComparePasswordBehavior : Behavior<PasswordBox>
{
protected override void OnAttached()
{
AssociatedObject.LostFocus += OnComparePasswordLostFocus;
base.OnAttached();
}
protected override void OnDetaching()
{
AssociatedObject.LostFocus -= OnComparePasswordLostFocus;
base.OnDetaching();
}
public static readonly DependencyProperty OriginalPasswordProperty =
DependencyProperty.Register("OriginalPassword", typeof(SecureString), typeof(ComparePasswordBehavior), new PropertyMetadata(null));
private static void OnComparePasswordLostFocus( object sender, RoutedEventArgs e )
{
PasswordBox pswdBox = sender as PasswordBox;
var behavior = Interaction.GetBehaviors(pswdBox).OfType<ComparePasswordBehavior>().FirstOrDefault();
if (behavior != null)
{
var binding = BindingOperations.GetBindingExpression( behavior, OriginalPasswordProperty);
PropertyInfo propInfo = binding.DataItem.GetType().GetProperty(binding.ParentBinding.Path.Path);
// at this point I am stumped. I don't seems to be able to
// retrieve the value from the original password box element.
// I am also not able to set the IsEnabled property of the ViewModel.
}
}
public SecureString OriginalPassword
{
get { return ( SecureString )GetValue( OriginalPasswordProperty ); }
set { SetValue( OriginalPasswordProperty, ( SecureString )value ); }
}
}
我在我的行为中定义了一个依赖属性来保存原始密码框中的密码值。在我的行为的 lostfocus 事件中,我需要比较两个密码并相应地设置我的 ViewModel 的 IsEnabled 属性。
我需要在这里做两件事。我需要从 Password1 PasswordBox 元素中检索密码值 我还需要根据密码比较结果设置我的 ViewModel 的 IsEnabled 属性。有人可以帮忙吗?我已经被困在这里一天了。谢谢。
【问题讨论】:
-
不要删除您的问题 - 在某种程度上,我希望这个问题能够吸引更多来自搜索引擎的访问