开发者

call a delegate from click event using C++/CLI

In C#, We can call a new function from button click with arguments like this,

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

and set this function on click event of a command button like this,

button1开发者_如何学JAVA.Click += delegate { mydelegate with argument };

Eg:

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

Now when we click on the button1, then the function "Method1" will be invoke.

How can I do the same using C++/CLI?

I need to find the added delegate from the click event and need to remove. How can i do this?


If you're asking about how to use anonymous delegates in C++/CLI, then the answer is you can't. In C++/CLI, delegates must be bound to a named function.

To accomplish what inline anonymous delegates actually do in C#, you can use the concept of a 'functor' or function object. The following C++/CLI sample illustrates how to create a function object and "bind" it to a specific value and then show how to use it as an event subscriber.

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


Thank you for your help. With your help I can solve my problem. The solution is like this,

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

}

Now when we click on button one, then the application call the function "MyFunction" with value 10,20 and when we click on button 2 then the same function "MyFunction" with value 100,200.

Thank you for your help.

Sabeesh

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜