我正在尝试将我的一些UI内容(文本框中的文本)作为参数提取到位于我的ViewModel中的ICommand方法中。
首先,我得到了这个RelayCommand实现:
/// <summary>
/// A command whose sole purpose is to relay its functionality to other
/// objects by invoking delegates. The default return value for the
/// CanExecute method is 'true'.
/// </summary>
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameters)
{
return _canExecute == null ? true : _canExecute(parameters);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameters)
{
_execute(parameters);
}
#endregion // ICommand Members
}
我在我的ViewModel中声明了一个命令:
public ICommand AddEntityCommand
{
get
{
if(_addEntity == null)
{
_addEntity = new RelayCommand(AddEntityToDb);
}
return _addEntity;
}
}
这是我的xaml定义:
<Label Content="Entity Name:" Name="label1"/>
<TextBox Name="textBox_EntityName" />
<Label Content="Entity Type:" Name="label2" />
<TextBox Name="textBox_EntityType" />
<Button Content="Add" Name="btnAdd" Command="{Binding Path=AddEntityCommand}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource MultiParamConverter}">
<Binding Path="Text" ElementName="textBox_EntityName" />
<Binding Path="Text" ElementName="textBox_EntityType" />
</MultiBinding>
</Button.CommandParameter>
</Button>
最后那是我的转换器:
public class MultiParamConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (object)values;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
我多次调试了这个工具,一旦我在文本框中更改了值,调试器就会在转换器内停止。在这种情况下,UI中的值显示在
中object[] values
参数。 单击按钮,不会让我在转换中停止,但它会调用方法
AddEntityToDb
正确,但是参数,其类型为object [],总是包含两个都为null的元素。
我认为创建AddEntityCommand时我做了一些非常错误的事情,但我无法自己解决这个问题。 但是AddEntityToDb的参数总是包含两个null元素的原因是什么?
答案 0 :(得分:3)
我不知道为什么它没有按预期工作,但无论如何你真的不需要使用命令参数......你可以将文本框绑定到ViewModel的属性,并使用这些属性的值在您的AddEntityToDb
方法中。这是在MVVM中最常用的方法......
编辑: 我转发了转换器的初始问题。我认为原因是MultiBinding
在调用values
之后清除Convert
数组(可能是为了避免内存泄漏)。修复是克隆数组而不是直接返回:
using System.Linq;
...
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return values.ToArray();
}
答案 1 :(得分:0)
更新:试试这个
public class MultiParamConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return new Tuple<string, string>((string)values[0], (string)values[1]);;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
视图模型
public void AddEntityToDb(object parameter)
{
var values = (Tuple<string, string>)parameter;
var text1 = values.Item1;
var text2 = values.Item2;
}