【问题标题】:Pass two UIElements as CommandParameter将两个 UIElements 作为 CommandParameter 传递
【发布时间】:2020-01-04 18:53:48
【问题描述】:

我有一个Prism MVVM 应用程序,可以轻松地将一个UIElement 作为CommandParameter 传递给ViewModel 的Command。但现在我想传递两个 UIElement。使用此 XAML:

<Button.CommandParameter>
    <MultiBinding Converter="{StaticResource DummyMultiConverter}">
        <Binding ElementName="PasswordBoxType"/>
        <Binding ElementName="PasswordBoxRetype"/>
    </MultiBinding>
</Button.CommandParameter>

使用这个Converter

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

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

还有一个简单的 DelegateCommand 在 ViewModel 中:

private DelegateCommand<object> _commandCloseDialogOK;
public DelegateCommand<object> CommandCloseDialogOK =>
    _commandCloseDialogOK ??
    (_commandCloseDialogOK = new DelegateCommand<object>(commandParameter=> CommandCloseDialogOKExecute(commandParameter)));

public virtual void CommandCloseDialogOKExecute(object commandParameter)
{
    RaiseRequestClose(new DialogResult(ButtonResult.OK));
}

public virtual bool CanExecuteCommandCloseDialogOK()
{
    return true;
}

当它运行时 - Convert 方法正确获取 values,作为 2 个 PasswordBoxes 的数组。但是 CommandCloseDialogOKExecute 将其 commandParameter 参数作为两个 nulls 的数组获取。如果我将 commandParameter 定义为 object[] 而不是 object,也会发生同样的情况。我应该怎么做 commandParameter 将是两个 PasswordBoxes 的数组?

【问题讨论】:

    标签: wpf mvvm prism


    【解决方案1】:

    首先,如果您使用的是 MVVM,那么您真的不应该将与视图相关的数据(如 UIElement 的数据)传递给视图模型。

    假设您知道这一点并且这确实是一个简化的描述来说明您的问题,问题在于框架在 Convert 返回的值应用于绑定之前显式清除了传递给 Convert 方法的数组。结果是它应用了现在为空的数组(null):

    https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Data/MultiBindingExpression.cs,1267

    您可以通过在 Convert 方法中创建另一个数组来避免这种情况:

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return new []{values[0], values[1]};
    }
    

    【讨论】:

    • “问题是你的多转换器返回的数组是一个本地参数,当转换方法返回时超出范围。”我不相信那是正确的。它是一个数组——一个引用类型——如果你仍然有对它的引用(在这种情况下是返回值),它就不能“超出范围”......
    • ...相反,原因是框架在将 Convert 返回的值应用于绑定之前显式清除了传入 Convert 方法的数组。结果是它应用了现在为空的数组(null):referencesource.microsoft.com/#PresentationFramework/src/…
    • 您当然是对的,感谢您澄清这一点!代码异味一直存在于您无法直接控制的对象(在本例中为数组)。
    猜你喜欢
    • 2014-04-22
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 2016-04-10
    • 2016-02-05
    • 1970-01-01
    相关资源
    最近更新 更多