Как передать 2 PasswordBox в качестве CommandParameter для команды?

В WPF PasswordBox.Password не является DP, поэтому мы не можем напрямую привязать его к ViewModel. Я выполнил онлайн-поиск, использовал эти методы, но преобразователь вызывается только один раз при загрузке представления, поэтому параметр в ExecuteMyCommand равен нулю:

MainWindow.xaml

    <DockPanel x:Name="WindowLayout" LastChildFill="False">
        <Grid DockPanel.Dock="Top" Margin="10">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock Text="PasswordBox1" VerticalAlignment="Center"/>
            <PasswordBox x:Name="PswBox" Grid.Column="1" Height="27"/>
            <TextBlock Text="PasswordBox2" VerticalAlignment="Center" Grid.Row="1"/>
            <PasswordBox x:Name="AgainPswBox" Grid.Column="1" Grid.Row="1" Height="27"/>
        </Grid>

        <Button IsDefault="True" Command="{Binding MyCommand}" DockPanel.Dock="Top" Content="Click" Width="60" Margin="10">
            <Button.CommandParameter>
                <MultiBinding Converter="{cvt:PlainMultiValueConverter}">
                    <Binding ElementName="PswBox"/>
                    <Binding ElementName="AgainPswBox"/>
                </MultiBinding>
            </Button.CommandParameter>
        </Button>
    </DockPanel>
</Window>

Converters\PlainMultiValueConverter.cs

namespace MVVM_Light_Base.Converters
{
    [MarkupExtensionReturnType(typeof(PlainMultiValueConverter))]
    //[ValueConversion(typeof(object[]), typeof(object))]
    public class PlainMultiValueConverter : MarkupExtension,
        IMultiValueConverter
    {
        public static PlainMultiValueConverter converter = null;

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (null == converter)
            {
                converter = new PlainMultiValueConverter();
            }
            return converter;
        }

        public object Convert(object[] values, Type targetType,
            object parameter, System.Globalization.CultureInfo culture)
        {
            return values;
        }

        public object[] ConvertBack(object value, Type[] targetTypes,
            object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Вьюмодел\Маинвиевмодел.кс

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Windows.Controls;
namespace MVVM_Light_Base.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        private RelayCommand<object> myCommand;

        public RelayCommand<object> MyCommand
        {
            get
            {
                return myCommand ?? (myCommand =
                    new RelayCommand<object>(ExecuteMyCommand));
            }
        }

        private void ExecuteMyCommand(object parameter)
        {
            var pswBoxes = parameter as object[];
            PasswordBox pb;
            string psw0;
            string psw1;

            try
            {
                pb = pswBoxes[0] as PasswordBox;
                psw0 = pb.Password;
                pb = pswBoxes[1] as PasswordBox;
                psw1 = pb.Password;
            }
            catch
            {
                return;
            }
        }
    }
}

введите здесь описание изображения

Почему конвертер не работал идеально? И как мне поступить?


person SubmarineX    schedule 19.04.2014    source источник


Ответы (2)


Вместо того, чтобы возвращать массив из конвертера, преобразуйте массив в новый список и передайте из конвертера.

Конвертер

public object Convert(object[] values, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
{
   return values.ToList();
}

Метод команды

private void ExecuteMyCommand(object parameter)
{
   var pswBoxes = parameter as List<object>;
   .....
}
person Rohit Vats    schedule 19.04.2014
comment
Идеально. Но я не знаю, зачем нужно «возвращать values.ToList()»? - person SubmarineX; 19.04.2014
comment
Передавая значения напрямую, вы фактически передаете ссылку на массив. Таким образом, любое изменение в массиве отразится на его использовании. Не уверен, какое действие возвращает объекты к нулю (может быть, какой-то код при загрузке XAML). Таким образом, с помощью ToList() вы создаете новую ссылку и передаете ее в ViewModel, которая не изменится ни при каком обновлении в массиве значений. - person Rohit Vats; 19.04.2014

Ну на самом деле проблема в вашем конвертере. Вам не нужно реализовывать MarkupExtension. Просто IMultivalueConverter.

public class PlainMultiValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        return values;
    }

    public object[] ConvertBack(object value, Type[] targetTypes,
        object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Затем объявите свой преобразователь как ресурс в вашем XAML и используйте его как простой {StaticResource MyConverter}.

<DockPanel x:Name="WindowLayout" LastChildFill="False">
    <DockPanel.Resources>
        <local:PlainMultiValueConverter x:Key="PlainMultiValueConverter"/>
    </DockPanel.Resources>
<!--...-->
    <Button IsDefault="True" Command="{Binding MyCommand}" DockPanel.Dock="Top" Content="Click" Width="60" Margin="10">
        <Button.CommandParameter>
            <MultiBinding Converter="{StaticResource PlainMultiValueConverter}">
                <Binding ElementName="PswBox"/>
                <Binding ElementName="AgainPswBox"/>
            </MultiBinding>
        </Button.CommandParameter>
    </Button>
</DockPanel>
person Dmitry    schedule 19.04.2014
comment
PlainMultiValueConverter, наследующий MarkupExtension, просто реализует шаблон singleton. - person SubmarineX; 19.04.2014