c# - MVVM WPF Multibinding 不适用于命令参数

标签 c# wpf mvvm command multibinding

我无法使多重绑定(bind)适用于两个密码框。我确实在网上阅读了很多文章尝试工作示例,但没有一个与我尝试过的场景相同。问题是当我点击登录按钮时,这些密码字段不会传输到命令 Execute 方法。

转换器的 XAML:

<Grid.Resources>
    <converter:PasswordConverter x:Key="passwordConverter"/>
</Grid.Resources>

按钮的 XAML 如下所示:
<Button x:Name="loginButton" 
                Content="Belépés" 
                Margin="494,430,0,0" 
                VerticalAlignment="Top" 
                FontSize="20" 
                RenderTransformOrigin="-2.624,8.99" 
                HorizontalAlignment="Left" 
                Width="172"
                Command="{Binding NavCommand}">
            <Button.CommandParameter>
                <MultiBinding Converter="{StaticResource passwordConverter}" Mode="TwoWay">
                    <Binding Path="Password" ElementName="userIDPasswordBox"/>
                    <Binding Path="Password" ElementName="leaderIDPasswordBox"/>
                </MultiBinding>
            </Button.CommandParameter>
        </Button>

密码转换器代码:
public class PasswordConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values.Clone();
    }

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

中继命令:
public class RelayCommand : ICommand
{

    Action _TargetExecuteMethod;
    Func<bool> _TargetCanExecuteMethod;

    public RelayCommand(Action executeMethod)
    {
        _TargetExecuteMethod = executeMethod;
    }

    public RelayCommand(Action executeMethod, Func<bool> canExecuteMethod)
    {
        _TargetExecuteMethod = executeMethod;
        _TargetCanExecuteMethod = canExecuteMethod;
    }

    public void RaiseCanExecuteChanged()
    {
        CanExecuteChanged(this, EventArgs.Empty);
    }

    #region ICommand Members

    bool ICommand.CanExecute(object parameter)
    {

        if (_TargetCanExecuteMethod != null)
        {
            return _TargetCanExecuteMethod();
        }

        if (_TargetExecuteMethod != null)
        {
            return true;
        }

        return false;
    }

    public event EventHandler CanExecuteChanged = delegate { };

    void ICommand.Execute(object parameter)
    {
        if (_TargetExecuteMethod != null)
        {
            _TargetExecuteMethod();
        }
    }

    #endregion
}

以及 View 模型的最后一段代码:
public class LogonViewModel : BaseViewModel
{

private Action _loginActionComplete;
public LogonViewModel(Action loginActionComplete)
{
    _measureTimer = new Timer();
    _measureTimer.Interval = 500D;
    _measureTimer.Elapsed += measureTimer_Elapsed;
    _measureTimer.Start();
    _loginActionComplete = loginActionComplete;
    NavCommand = new RelayCommand(loginActionComplete);
    SerialPort = new SerailCommunicationNameSpace.SerialCommunication("COM3");
}

~LogonViewModel()
{
    SerialPort.Close();
}

public RelayCommand NavCommand { get; private set; }

private double _measuredWeight;
public double MeasuredWeight {
    get
    {
        return _measuredWeight;
    }
    set
    {
        SetProperty(ref _measuredWeight, value);
    }
}
private Timer _measureTimer;
public SerailCommunicationNameSpace.SerialCommunication SerialPort { get; set; }

private void measureTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    var measuredWeight = 0D;
    if (string.IsNullOrWhiteSpace(SerialPort.DataReceived) == false) {
        var dataReceivedStartTrim = SerialPort.DataReceived.TrimStart();
        var dataReceivedNumbersOnly = dataReceivedStartTrim.Substring(0, dataReceivedStartTrim.IndexOf(' '));
        var enUSCultureInfo = new CultureInfo("en-US");
        measuredWeight = double.Parse(dataReceivedNumbersOnly, enUSCultureInfo);
    }
    SetProperty(ref _measuredWeight, measuredWeight);
    OnPropertyChanged("MeasuredWeight");
}

public string LeaderId { get; set; }

public string UserId { get; set; }

}

最佳答案

问题是 Password PasswordBox 的属性(property)既不是依赖属性也不是实现 INotifyPropertyChanged .这意味着,密码的更改将不会应用于绑定(bind)。
例如。如果为 PasswordChanged 添加事件处理程序到PasswordBox并将密码设置为Tag属性,则可以绑定(bind)到 Tag并且绑定(bind)将起作用。

<Button x:Name="loginButton" 
        Content="Belépés" 
        Margin="494,430,0,0" 
        VerticalAlignment="Top" 
        FontSize="20" 
        RenderTransformOrigin="-2.624,8.99" 
        HorizontalAlignment="Left" 
        Width="172"
        Command="{Binding NavCommand}">
    <Button.CommandParameter>
        <MultiBinding Converter="{StaticResource passwordConverter}">
            <Binding Path="Tag" ElementName="userIDPasswordBox"/>
            <Binding Path="Tag" ElementName="leaderIDPasswordBox"/>
        </MultiBinding>
    </Button.CommandParameter>
</Button>

<PasswordBox Name="userIDPasswordBox" PasswordChanged="PasswordBox_PasswordChanged"/>
<PasswordBox Name="leaderIDPasswordBox" PasswordChanged="PasswordBox_PasswordChanged"/>

private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
    var pbx = sender as PasswordBox;
    if (pbx!=null)
    {
        pbx.Tag = pbx.Password;
    }
}

当然,为了避免实现背后的代码,您应该将事件处理程序移至行为。

关于c# - MVVM WPF Multibinding 不适用于命令参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54090474/

相关文章:

javascript - 如何在AngularJS或Javascript中实现类似C#的await的功能?

wpf - 为什么这有效? (在全景模板中绑定(bind),Windows Phone 7)

c# - 当模型包含另一个类的对象作为使用 DataAnnotations 的属性时,如何在控制台应用程序中验证 .Net Core 3.1 中的模型?

c# - 对异常执行操作并返回到上次访问的页面

c# - 如何根据其属性更改自定义控件的背景颜色

c# - 我如何为样式指定设计器数据上下文,以便 Resharper 找到我的属性?

wpf - Resource 中的 DataTemplate 将 ViewModel 设置为 View,但随后

.net - 用于 wpf mvvm 的 MVVM 工具包(模板)和 XAML powertoys 工作吗?

c# - 使用 Xamarin 表单的 HttpClient

c# - 如何在 xaml 中使用 List<T>?