gpt4 book ai didi

c# - 如何从命令对象中访问整个 ViewModel

转载 作者:行者123 更新时间:2023-11-29 21:26:59 25 4
gpt4 key购买 nike

基于@stuart 的 blog post ,我可以看到如何将文字字符串作为 CommandParameter 进行绑定(bind)。

local:MvxBind="Click FindUserCommand, CommandParameter=foo"
public class FindUserViewModel: ViewModelBase
{
public FindUserViewModel(IFindUserCommand findUserCommand)
{
_findUserCommand = findUserCommand;
}

// class truncated for brevity

private IFindUserCommand _findUserCommand;
public IFindUserCommand FindUserCommand
{
get { return _findUserCommand; }
set { _findUserCommand = value; RaisePropertyChanged(() = > FindUserCommand); }
}
}
public class FindUserCommand: IFindUserCommand
{
// class truncated for brevity
public void Execute(object parameter)
{
// RIGHT HERE:
// value of parameter == foo
}
}

当 Command 存在于它自己的命令对象而不是 ViewModel 中时,如何将整个 ViewModel 绑定(bind)为 Button 的 CommandParameter?

public void Execute(object parameter)
{
var vm = (FindUserViewModel)parameter;
var firstName = vm.FirstName;
var lastName = vm.LastName;
// etc...
}

注意:如果我必须以某种方式扩展 MvvmCross 以使用类似于 WPF 的统一方式来实现此功能,我可以接受。我只是不知道从哪里开始。


我找到的所有示例都直接在 ViewModel 中声明命令,如下所示:

MvvmCross 示例

private Cirrious.MvvmCross.ViewModels.MvxCommand _insertCommand;
public System.Windows.Input.ICommand InsertCommand
{
get
{
_insertCommand = _insertCommand ? ? new Cirrious.MvvmCross.ViewModels.MvxCommand(DoInsert);
return _insertCommand;
}
}

private int _countAdded = 0;

private void DoInsert()
{
_countAdded++;
var kitten = _kittenGenesisService.CreateNewKitten(_countAdded.ToString());
_dataService.Insert(kitten);
RefreshDataCount();
}

然后像这样将按钮绑定(bind)到 View :

<Button
android:text="Insert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button1"
local:MvxBind="Click InsertCommand" />

但我想在其自己的类文件中声明 Command 对象,以便它更易于测试,然后将其注入(inject) ViewModel。

Android 的 MVVMCross 中是否可以绑定(bind) CommandParameter,类似于 WPF 如何绑定(bind)其命令参数?


WPF 示例:

查看按钮定义:

<Button 
Command="{Binding SearchCommand}"
CommandParameter="{Binding}"/>

ViewModel 命令属性:

private ICommand _findUserCommand;
public ICommand FindUserCommand
{
get { return _findUserCommand; }
set { _findUserCommand = value; RaisePropertyChanged( () => FindUserCommand ); }
}

命令对象定义:

public class FindUserCommand : ICommand
{
private readonly IUserService _userService;

public FindUserCommand(IUserService userService)
{
_userService = userService;
}

public bool CanExecute ( object parameter )
{
var findUserViewModel = ( FindUserViewModel )parameter;
return findUserViewModel.NameSearch.Length > 0;
}

public void Execute ( object parameter )
{
FindUserViewModel.Users = _userService.Find( FindUserViewModel.NameSearch );
}

public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged ()
{
if ( CanExecuteChanged != null )
CanExecuteChanged( this, new EventArgs() );
}
}

最佳答案

默认情况下,Android 小部件(如按钮)没有 Command 和 CommandParameter 成员 - 因此无法“开箱即用”地使用它们。

但是,您可以轻松地从 Button 继承以生成 MyButton,然后您可以提供 CommandCommandParameter成员,如果你想 - 例如像这样的东西:

public class MyButton : Button
{
public MyButton(Context c, IAttributeSet a) : base(c,a)
{
Click += (s,e) => {
if (Command == null) return;
if (!Command.CanExecute(CommandParameter)) return;
Command.Execute(CommandParameter);
};
}

public ICommand Command { get;set; }
public object CommandParameter { get;set; }
}

使用它,您可以在您的 axml 中使用 MyButton 而不是 Button

 <MyButton
local:MvxBind="Command SearchCommand;CommandParameter ." />

有关数据绑定(bind)的更多信息,请参阅 https://github.com/MvvmCross/MvvmCross/wiki/Databinding


或者,另一种方法是使用基于 ValueConverter 的方法——类似于 MvvmCross 提供的 CommandParameter 功能——参见 http://slodge.blogspot.co.uk/2013/06/commandparameter-binding.html

关于c# - 如何从命令对象中访问整个 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20101125/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com