2010-09-19 50 views
2

在C#中從click事件的委託,我們可以調用從按鈕單擊一個新的功能,像這樣的論點,調用使用C++/CLI

////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的,則函數 「方法一」 將invok即

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

我需要從click事件中找到添加的委託並需要刪除。我怎樣才能做到這一點?

回答

3

如果您在C++/CLI中詢問如何使用匿名委託人,那麼答案是不可以。在C++/CLI中,委託必須綁定到一個命名函數。

要完成內聯匿名代表在C#中實際執行的操作,可以使用'functor'或的概念。以下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; 
} 
+0

謝謝您的回答。 – sabeesh 2010-09-19 05:40:23

+1

你不能*繼續*。 C++ 0x添加lambdas,爲C++首次提供了匿名方法的語法。就個人而言,我很高興微軟等待標準委員會就語法達成一致意見,而不是添加一些不可移植的擴展,並以受管vs本地代碼中的lambda表達式的不同語法結束。 – 2010-09-20 17:08:58

+0

我需要從click事件中找到添加的委託並需要刪除。我怎樣才能做到這一點? – sabeesh 2010-09-22 12:01:27

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

//函子.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); 

} 

現在,當我們點擊按鈕1時,應用程序調用值爲10,20的函數「MyFunction」,當我們點擊按鈕2時,同樣的函數「MyFunction」的值爲100,200。

謝謝你的幫助。

Sabeesh

+1

請編輯你的問題,而不是在這裏添加答案。你應該刪除它。 請參閱我的最新回覆以瞭解您後續問題的答案。 – bobbymcr 2010-09-19 06:15:58