使用C ++ / CLI从click事件中调用委托

时间:2010-09-19 05:14:37

标签: delegates c++-cli

在C#中,我们可以通过按钮点击调用一个新函数,使用这样的参数,

    ////My function
    public static void Method1(int x)
    {
        Console.WriteLine("Method 1");
    }

并在此命令按钮的单击事件上设置此功能,

button1.Click += delegate { mydelegate with argument };

例如:

delegate void Procedure( int x);

public partial class Window1 : Window
{
    public Window1()
    {
        Procedure pProcedure = new Procedure(Method1);
        InitializeComponent();

        button1.Click += delegate { pProcedure(10); };
    }

    public static void Method1(int x)
    {
        Console.WriteLine("Method 1");
    }
}

现在,当我们点击button1时,将调用函数“Method1”。

如何使用C ++ / CLI执行相同操作?

我需要从click事件中找到添加的委托,需要删除。我怎么能这样做?

2 个答案:

答案 0 :(得分:3)

如果您在C ++ / CLI中询问如何使用匿名代理,那么答案是您不能。在C ++ / CLI中,委托必须绑定到命名函数。

要完成内联匿名委托在C#中实际执行的操作,您可以使用“仿函数”或function object的概念。以下C ++ / CLI示例说明了如何创建函数对象并将其“绑定”到特定值,然后展示如何将其用作事件订阅者。

using namespace System;

// Sample class with one event 'Started' 
public ref class Widget
{ 
public:
    Widget()
    {
    }

    event EventHandler ^ Started;

    void Start()
    {
        Console::WriteLine("Starting...");
        Started(this, EventArgs::Empty);
    }
};

// Declare 'functor' class to capture state
private ref class Functor
{
public:
    Functor(int input)
        : input_(input)
    {
    }

    // This is what we will use as the handler method
    void Handler(Object ^ sender, EventArgs ^ e)
    {
        Console::WriteLine(L"Invoked with input {0}.", input_);
    }

private:
    int input_;
};

// Entry point
int wmain(int argc, wchar_t ** argv)
{
    // Create a functor to capture value '10'
    Functor ^ f = gcnew Functor(10);

    Widget ^ widget = gcnew Widget();

    // Subscribe to event using functor's handler
    // (note that we bind to the instance 'f' here)
    EventHandler ^ handler = gcnew EventHandler(f, &Functor::Handler);
    widget->Started += handler;

    // Should print "Invoked with input 10."
    widget->Start();

    // Remove the handler
    widget->Started -= handler;

    // Should not print anything extra now
    widget->Start();

    return 0;
}

答案 1 :(得分:1)

感谢您的帮助。 在你的帮助下,我可以解决我的问题。 解决方案是这样的,

// FirstWindow.h

#pragma once

using namespace System;
using namespace System::Windows;
using namespace System::Windows::Controls;

ref class Functor;

ref class FirstWindow : Window
{
    Canvas^ maincanvas;
    Button^ addbutton1;
    Button^ addbutton2;
    Functor^ pFunctor;
public:
    FirstWindow(void);
    void InitControls(void);
    void MyFunction( int x, int y );
};

// FirstWindow.cpp

 #include "FirstWindow.h"
 #include "Functor.h"

FirstWindow::FirstWindow(void)
{
    Title = "First Avalon App";
    Width = 400;
    Height = 400;
    ResizeMode = System::Windows::ResizeMode::NoResize;

    InitControls();
}

void FirstWindow::InitControls(void)
{
        addbutton1 = gcnew Button();
        addbutton1->Width = 80;
        addbutton1->Height = 25;
        addbutton1->Content = "Add";
        pFunctor = gcnew Functor(this, 10, 20);
        addbutton1->Click += gcnew RoutedEventHandler( pFunctor, &Functor::Handler);

        Canvas::SetTop(addbutton1, 45);
        Canvas::SetLeft(addbutton1, 200);

        pFunctor = gcnew Functor(this, 100, 200);
        addbutton2 = gcnew Button();
        addbutton2->Width = 80;
        addbutton2->Height = 25;
        addbutton2->Content = "Add";
        addbutton2->Click += gcnew RoutedEventHandler(pFunctor, &Functor::Handler);

        Canvas::SetTop(addbutton2, 85);
        Canvas::SetLeft(addbutton2, 200);

        maincanvas = gcnew Canvas();        

        maincanvas->Children->Add(addbutton1);
        maincanvas->Children->Add(addbutton2);
        Content = maincanvas;
}

void FirstWindow::MyFunction( int x, int y )
{
    MessageBox::Show("This function is call by Button Click with values " + x.ToString() + " , " + y.ToString() );
}

// Functor.h

 #pragma once

using namespace System;
using namespace System::Windows;
using namespace System::Windows::Controls;

ref class FirstWindow;

private ref class Functor
{
public:
    Functor(FirstWindow^ pFirstWindow, int pFirstArg, int pSecArg);

    // This is what we will use as the handler method
    void Handler(Object ^ sender, RoutedEventArgs ^ e);

private:
    int m_pFirstArg;
    int m_pSecArg;
    FirstWindow^ m_pFirstWindow;
};

// Functor.cpp

 #include "Functor.h"
 #include "FirstWindow.h"

Functor::Functor(FirstWindow^ pFirstWindow, int pFirstArg, int pSecArg) : m_pFirstWindow( pFirstWindow ),  m_pFirstArg(pFirstArg), m_pSecArg( pSecArg )
{

}

void Functor::Handler(Object ^ sender, RoutedEventArgs ^ e)
{
    if ( m_pFirstWindow )
        m_pFirstWindow->MyFunction(m_pFirstArg, m_pSecArg );

}

现在,当我们点击第一个按钮时,应用程序调用值为10,20的函数“MyFunction”,当我们点击按钮2时,然后使用值为100,200的相同函数“MyFunction”。

感谢您的帮助。

Sabeesh