【问题标题】:What is the event handler equivilent to the LINQ code used here与此处使用的 LINQ 代码等效的事件处理程序是什么
【发布时间】:2016-06-25 14:06:57
【问题描述】:

我看过一些关于 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
    );

我知道它在做什么。但如果我的代码变得更复杂,我会更喜欢专用的处理程序。如何定义这个处理程序?

谢谢。

【问题讨论】:

    标签: c# wpf linq


    【解决方案1】:

    澄清一下,这不是 linq,它只是作为参数传递的 lambda 方法。

    如果你想坚持使用 DelegateCommand 类,另一种选择是定义方法而不是通过替换传递 lambda:

    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 语法内联的方法的重点是让代码显示在使用它的位置,这对于小型不可重复使用的 sn-ps 非常有用。另请注意,在您的 lambda 语法版本中,可以简化 CanExecute(单个语句,可以删除括号并返回),并且没有理由将所有内容写在一行中(因此在 Execute 中,每个语句都可以在它自己的行上) .我会这样重写它:

    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);
    }
    

    【讨论】:

    • 感谢您的澄清和建议!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 2011-09-06
    相关资源
    最近更新 更多