C# 委托、操作、事件、Lambda表达式和MVVM

C# 委托、操作、事件、Lambda表达式和MVVM,c#,wpf,events,mvvm,delegates,C#,Wpf,Events,Mvvm,Delegates,我花了几天时间试图理解WPF和MVVM。进展非常缓慢,主要是因为我对一些事件和东西缺乏了解。下面,我将试图解释我对所有这些事情的理解: 方法——这个方法很简单,我认为不需要任何解释。任何程序的基本要素 委托–我认为它是指针指向方法。我能想到的只有很少几个应用程序,我想在方法上使用它 行动——这一点更为棘手。我设法找到的信息说它是一个不返回值的委托。。。那么,它只是void方法上的指针吗?我不明白那有什么意义 事件——这件事我一点也不明白。这是与代表解释,我不明白它是如何工作的,它是为了什么。注

我花了几天时间试图理解WPF和MVVM。进展非常缓慢,主要是因为我对一些事件和东西缺乏了解。下面,我将试图解释我对所有这些事情的理解:


方法——这个方法很简单,我认为不需要任何解释。任何程序的基本要素

委托–我认为它是指针指向方法。我能想到的只有很少几个应用程序,我想在方法上使用它

行动——这一点更为棘手。我设法找到的信息说它是一个不返回值的委托。。。那么,它只是void方法上的指针吗?我不明白那有什么意义

事件——这件事我一点也不明白。这是与代表解释,我不明白它是如何工作的,它是为了什么。注意:我使用事件编写winforms应用程序,但它只是从列表中选择所需的事件

事件处理程序——甚至更不清楚

Lambda表达式–也是使用方法的另一种方式。我再次理解它不会返回任何东西,我可以在其中传递一些参数,但与void方法没有太大区别。我见过一些应用程序,比如使用LINQ时,但我仍然不明白它是如何工作的


首先,我想说,我了解MVVM的基本构造、正在做什么等等。我的问题是,我不理解一些代码,它是如何工作的,因此我不能自己写任何东西。我将使用一些教程作为示例,如下所示:

S1:

S2:

我希望你们能给我一些指导或解释,我怎样才能接近和理解这些想法,使它们至少对我来说不那么可怕。这里我将举一些例子,希望能告诉你我有什么样的问题


1) 第一个来自著名的RelayCommand类的S1:

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
我知道它应该做什么(名字不言而喻)。但我不明白这是怎么回事?它如何知道何时使某些内容可执行,何时不可执行。那些添加和删除“命令”到底是什么?我想读一下,但没用

2) 另一个示例表格S1:

    #region CloseCommand

    /// <summary>
    /// Returns the command that, when invoked, attempts
    /// to remove this workspace from the user interface.
    /// </summary>
    public ICommand CloseCommand
    {
        get
        {
            if (_closeCommand == null)
                _closeCommand = new RelayCommand(param => this.OnRequestClose());

            return _closeCommand;
        }
    }

    #endregion // CloseCommand

    #region RequestClose [event]

    /// <summary>
    /// Raised when this workspace should be removed from the UI.
    /// </summary>
    public event EventHandler RequestClose;

    void OnRequestClose()
    {
        EventHandler handler = this.RequestClose;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }

    #endregion // RequestClose [event]
#区域关闭命令
/// 
///返回调用时尝试执行的命令
///从用户界面中删除此工作区。
/// 
公共ICommand CloseCommand
{
得到
{
如果(_closeCommand==null)
_closeCommand=newrelaycommand(param=>this.OnRequestClose());
返回关闭命令;
}
}
#endregion//CloseCommand
#区域请求关闭[事件]
/// 
///当应从UI中删除此工作区时引发。
/// 
公共事件事件处理程序RequestClose;
void OnRequestClose()
{
EventHandler=this.RequestClose;
if(处理程序!=null)
处理程序(此,EventArgs.Empty);
}
#endregion//RequestClose[事件]
再一次,我知道它应该做什么,我甚至知道这里基本上发生了什么,但我不知道这个“东西”实际上在做什么。OnRequestClose()只是创建了一个处理程序,在我看来,这个处理程序不会关闭任何它应该关闭的东西。问题是,若我甚至不知道命令在哪里执行,我怎么能编写自己的命令

3) 我想这将是最后一个例子,这次来自S2:

public ViewModel()
{
    _clickCommand = new DelegateCommand<string>(
        (s) => { /* perform some action */ }, //Execute
        (s) => { return !string.IsNullOrEmpty(_input); } //CanExecute
        );
}
公共视图模型()
{
_clickCommand=新建委派命令(
(s) =>{/*执行一些操作*/},//执行
(s) =>{return!string.IsNullOrEmpty(_input);}//CanExecute
);
}
这里的问题很简单。它正在使用RelayCommand-ctor创建命令(或者至少它在本项目中的版本,这里称为“DelegateCommand”)。我不明白这些和lambda的用法。这是干什么用的


当然,这并不是我的全部问题,但我想这会让任何愿意帮助我的人知道我的问题所在。我尽可能地解释我的问题,我非常感谢任何帮助或指导。也许我对自己期望很高,但我觉得我需要了解所有这些东西,才能写出严肃的作品


无论如何,提前感谢大家的帮助。

对于您的广泛问题,我有一个很长的答案

让我先用一种简单的方法深入研究事件和事件处理程序

假设你所在的城市举办了一个大型活动,将接待许多来自你所在国家的名人

让我们考虑三个客人的例子 客人一是其他客人不认识的人
客人二是您所在地区的名人,很少有人知道
客人三在你们国家很有名

考虑以下假设

没有人在等待来宾1(0 EventHandler)

有四个 等待客人的人每人有两(4)名事件处理人 等待问候的事件处理程序)

有三名安保人员和10名客人(其中一人 还有人在等客人2)等客人3(13 EventHandler(事件处理程序)

情景1 当一号客人到达会场(活动开始)时,什么都没有发生

情景2 当客人二到达会场(活动开始)时,四个人走向他/她并致以问候

情景3 当三号客人到达(活动)时,你会看到安全部队提供掩护,十个人向他/她走去并打招呼

要遵守的简单要点
1.事件只是发生了某件事的通知(如具有方法签名的委托)
2.EventHandler是关于特定事件发生时发生什么的操作(方法)
class Program
{
    static void Main(string[] args)
    {
        var test = new Example();
        Console.ReadLine();
    }
}


class Example
{
    //This is the event definition
    delegate void ActionDelegate(string input1, string input2);

    // Two event handler which implements the signature of the event
    void ActionMethod(string a, string b)
    {
        Console.WriteLine(a + " " + b);
    }
    void ActionMethod2(string c, string d)
    {
        Console.WriteLine("Wow one more function called with parameter {0} and {1}", c, d);
    }

    delegate Tuple<string, string> LamdaDelegate(string input1, string input2);
    public Example()
    {
        //Did not declare any delegate member variable explicitly.
        //Clean and easy to understand
        Action<string, string> action = ActionMethod;

        // Had to define the delegate with method signature explicitly before using it
        ActionDelegate actionDelegate = ActionMethod; 
        actionDelegate += ActionMethod2; // Attaching more event handlers to the event

        //The below lambda expression implicitly means that it will take two inputs each of type string
        // and does not return anything. 
        //The type information is implicitly derived from the method signature of the delegate
        actionDelegate += (a, b) => Console.WriteLine("Called using lambda expression");


        //Below is a Lambda expression in which s and e each is of type string 
        //Since the return type of the delegate is Tuple<string,string> the same is returned by the expression
        //Lambda expression is using a delegate without defining a delegate explicitly. 
        LamdaDelegate myTuple = (s, e) => { return Tuple.Create(s, e); };

        //The above Lambda can be rewritten as
        myTuple += delegate (string a, string b) { return Tuple.Create(a, b); };

        //Invoking the event handlers. The event handlers are executed automatically when ever the event occurs 
        action("Hi", "called from action");
        actionDelegate("Hi", "called using explicitly defined delegate");
    }
}
bool IsGreaterThan5(int number)
{
  return number > 5;
}

var isGreaterThan5 = new Func<int, bool>(number => number > 5);
int[] numbers = new []{ 1, 2, 3 4, 5, 6, 7 };
var filteredNumbers = numbers.Where(IsGreaterThan5); //method IsGreaterThan5 is defined in previus example

//just another syntax:
var filteredNumbers = numbers.Where(number => number > 5);

//just another syntax:
var filteredNumbers = numbers.Where(new Func<int, bool>(number => number > 5));

//just another syntax:
Func<int, bool> isGreaterThan5 = i => i > 5; //it does not matter how you name the input parameter
var filteredNumbers = numbers.Where(isGreaterThan5);