我已经看过几个关于MVVW的教程,但我仍然不确定。
在此website上。结果我实现了它提供的方法:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace OCLMEditor
{
public class DelegateCommand<T> : System.Windows.Input.ICommand
{
private readonly Predicate<T> _canExecute;
private readonly Action<T> _execute;
public DelegateCommand(Action<T> execute)
: this(execute, null)
{
}
public DelegateCommand(Action<T> execute, Predicate<T> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (_canExecute == null)
return true;
return _canExecute((parameter == null) ? default(T) : (T)Convert.ChangeType(parameter, typeof(T)));
}
public void Execute(object parameter)
{
_execute((parameter == null) ? default(T) : (T)Convert.ChangeType(parameter, typeof(T)));
}
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
}
}
}
目前,在我的ViewModel中,我有这个:
public class OCLMEditorModelView
{
private readonly DelegateCommand<string> _DeleteStudentButtonClickCommand;
public ObservableCollection<Student> Students
{
get
{
return _Model.Students;
}
}
private Student _SelectedStudentItem;
public Student SelectedStudentItem
{
get { return _SelectedStudentItem; }
set
{
_SelectedStudentItem = value;
_DeleteStudentButtonClickCommand.RaiseCanExecuteChanged();
}
}
private OCLMEditorModel _Model;
public List<StudyPointItem> ReadingStudyPointsList { get; set; }
public List<StudyPointItem> StudentStudyPointsList { get; set; }
public List<String> TreasureItemMethodsList { get; set; }
public OCLMEditorModelView()
{
InitTreasureItemMethodsList();
InitReadingStudyPointsList();
InitStudentStudyPointsList();
_Model = new OCLMEditorModel();
_DeleteStudentButtonClickCommand = new DelegateCommand<string>(
(s) => { _Model.Students.Remove(_SelectedStudentItem); _Model.Serialize(); MessageBox.Show("Student deleted!"); }, //Execute
(s) => { return _SelectedStudentItem != null; } //CanExecute
);
}
public DelegateCommand<string> DeleteStudentButtonClickCommand
{
get { return _DeleteStudentButtonClickCommand; }
}
// Code snipped
}
为完整起见,按钮的XAML:
<Button x:Name="buttonDeleteStudent"
Content="Delete"
Margin="2"
Command="{Binding DeleteStudentButtonClickCommand}"/>
一切正常。但是我发现这段代码难以读取(LINQ):
_DeleteStudentButtonClickCommand = new DelegateCommand<string>(
(s) => { _Model.Students.Remove(_SelectedStudentItem); _Model.Serialize(); MessageBox.Show("Student deleted!"); }, //Execute
(s) => { return _SelectedStudentItem != null; } //CanExecute
);
我知道它在做什么。但是如果我的代码变得更复杂,我宁愿使用专用处理程序。我该如何定义这个处理程序?
谢谢。
答案 0 :(得分:2)
只是为了澄清,这不是linq,它只是作为参数传递的lambda方法。
如果你想坚持使用DelegateCommand类,另一种方法是通过替换来定义方法而不是传递lambdas:
public OCLMEditorModelView()
{
InitTreasureItemMethodsList();
InitReadingStudyPointsList();
InitStudentStudyPointsList();
_Model = new OCLMEditorModel();
_DeleteStudentButtonClickCommand = new DelegateCommand<string>(
(s) => { _Model.Students.Remove(_SelectedStudentItem); _Model.Serialize(); MessageBox.Show("Student deleted!"); }, //Execute
(s) => { return _SelectedStudentItem != null; } //CanExecute
);
}
带
public OCLMEditorModelView()
{
InitTreasureItemMethodsList();
InitReadingStudyPointsList();
InitStudentStudyPointsList();
_Model = new OCLMEditorModel();
_DeleteStudentButtonClickCommand = new DelegateCommand<string>(
ExecuteMethod, //Execute
CanExecuteMethod//CanExecute
);
}
void ExecuteMethod(string s)
{
_Model.Students.Remove(_SelectedStudentItem);
_Model.Serialize();
MessageBox.Show("Student deleted!");
}
bool CanExecuteMethod(string s)
{
return _SelectedStudentItem != null;
}
请注意,这实际上并没有添加任何可维护性,相反,如果您在其他地方重用这些方法代码,这是一件好事,但定义使用匿名方法或lambda语法内联的方法的要点是显示在使用它的代码,这对于小的不可重复使用的片段非常有用。另请注意,在lambda语法版本中,可以简化CanExecute(单个语句,可以删除括号并返回),并且没有理由将所有内容写入一行(因此在Execute中,每个语句都可以在其上;&#39;自己的路线)。我将其重写为:
public OCLMEditorModelView()
{
InitTreasureItemMethodsList();
InitReadingStudyPointsList();
InitStudentStudyPointsList();
_Model = new OCLMEditorModel();
_DeleteStudentButtonClickCommand = new DelegateCommand<string>(
(s) =>
{
_Model.Students.Remove(_SelectedStudentItem);
_Model.Serialize();
MessageBox.Show("Student deleted!");
},
(s) => _SelectedStudentItem != null);
}