C#触发事件

时间:2016-07-26 12:12:04

标签: c# events

我使用C#,我想从类中触发一个事件:

因此,如果类的Price属性已更改,则应触发事件onPriceChanged(类外)。 但是,我收到一个错误:

  

当前上下文中不存在名称“onPriceChanged”

我该如何解决这个问题? (我想我可以通过构造函数将eventhandler传递给类...但是如果可能的话我宁愿不将eventhandler传递给类)

这是我的代码:

using System;

public delegate void delEventHandler();

class clsItem
{
    //private static event delEventHandler _show;
    private delEventHandler _show;
    private int _price;

    public clsItem()  //Konstruktor
    {
        _show += new delEventHandler(Program.onPriceChanged);  //  error here :  The name 'onPriceChanged' does not exist in the current context
    }

    public int Price
    {
        set
        {
            _price = value;
            _show.Invoke();  //trigger Event when Price was changed
        }
    }
}

class Program
{
    static void Main()
    {
        clsItem myItem = new clsItem();
        myItem.Price = 123;   //this should trigger Event "onPriceChanged"
    }

    //EventHandler 
    public static void onPriceChanged()
    {
        Console.WriteLine("Price was changed");
    }
}

3 个答案:

答案 0 :(得分:2)

您以错误的方式执行此操作 - 您尝试从类中附加事件处理程序,并且显然无法访问Program.onPriceChanged方法!

您应公开您的活动,并从客户端代码(Program)附加事件处理程序。

class clsItem
{
    //private static event delEventHandler _show;
    private delEventHandler _show;
    private int _price;

    public clsItem()  //Konstruktor
    {

    }

    public event delEventHandler Show
    {
        add { _show += value; }
        remove { _show -= value; }
    }

    public int Price
    {
        set
        {
            _price = value;
            _show?.Invoke();  //trigger Event when Price was changed
        }
    }
}

clsItem myItem = new clsItem();
myItem.Show += onPriceChanged;
myItem.Price = 123;   //this now does trigger Event "onPriceChanged" 

实例:http://rextester.com/WMCQQ40264

答案 1 :(得分:0)

以下是更传统的做事方式:

public delegate void delEventHandler();

class clsItem
{
    public event delEventHandler Show;
    private int _price;

    public clsItem()  //Konstruktor
    {
    }

    public int Price
    {
        set
        {
            _price = value;
            Show?.Invoke();  //trigger Event when Price was changed
        }
    }
}

class Program
{
    static void Main()
    {
        clsItem myItem = new clsItem();
        myItem.Show += onPriceChanged;
        myItem.Price = 123;   //this should trigger Event "onPriceChanged"
    }

    //EventHandler 
    public static void onPriceChanged()
    {
        Console.WriteLine("Price was changed");
    }
}

请注意clsItem不再知道谁订阅了它的活动。所有它关心的是通知任何碰巧订阅的听众。 clsItemonPriceChanged方法之间不再存在依赖关系。

答案 2 :(得分:0)

你处理事件的方式不是一个好习惯。我们使用事件的原因是将我们创建的对象与他们需要调用的方法分离。

例如,如果你想创建另一个相同类型的对象(clsItem)并让它在价格改变后调用另一个方法,那么你会遇到麻烦。所以我建议使用此代码而不是当前代码:

using System;

public delegate void delEventHandler();

class clsItem
{
    public event delEventHandler PriceChanged;
    private int  _price;

    public clsItem()  //Konstruktor
    {

    }

    public int Price
    {
        set { 
              if(value!=_price) // Only trigger if the price is changed
              {
                _price = value;
                if(PriceChanged!=null) // Only run if the event is handled
                {
                    PriceChanged();
                }
              }
            }
    }   
}       

class Program
{   
    static void Main()
    {
       clsItem myItem = new clsItem();
       myItem.PriceChanged += new delEventHandler(onPriceChanged);
       myItem.Price = 123;   //this should trigger Event "PriceChanged" and call the onPriceChanged method
    }

    //EventHandler 
    public static void onPriceChanged()
    {
        Console.WriteLine("Price was changed");
    }
}