вызвать делегата из события click, используя C ++ / CLI - PullRequest
2 голосов
/ 19 сентября 2010

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

Теперь, когда мы нажмем кнопку1, будет вызвана функция «Метод1».

Как я могу сделать то же самое с помощью C ++ / CLI?

Мне нужно найти добавленного делегата в событии click и его нужно удалить.Как я могу это сделать?

Ответы [ 2 ]

3 голосов
/ 19 сентября 2010

Если вы спрашиваете о том, как использовать анонимных делегатов в C ++ / CLI, то ответ - вы не можете. В C ++ / CLI делегаты должны быть связаны с именованной функцией.

Чтобы выполнить то, что в действительности делают встроенные анонимные делегаты в C #, вы можете использовать концепцию «функтора» или объекта функции . В следующем примере 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 голос
/ 19 сентября 2010

Спасибо за вашу помощь.С вашей помощью я могу решить мою проблему.Решение выглядит следующим образом:

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

}

Теперь, когда мы нажимаем на кнопку один, приложение вызывает функцию «MyFunction» со значением 10,20, а когда мы нажимаем на кнопку 2, то жефункция «MyFunction» со значением 100,200.

Спасибо за помощь.

Sabeesh

...