Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Objective-C

Handle Managed(C#) Event in Managed(C++/CLI)

4.55/5 (13 votes)
10 Oct 2022CPOL 29.9K   481  
Handle managed (C#) event in managed (C++/CLI)
In this article I explain how to call event from managed C# application to managed C++/CLI

Introduction

While working with one project, we had a requiremnet in which an event had to be raised from managed application and had to handle that event in managed C++ application. We read many articles and blogs but did not get a proper example. After spending two days, we managed to handle the event in managed C++. So, I added this tip which might help others.

Implementing a Library for Event in C#

As a first step, implement managed library that raises an event.

Create a new C# Class Library project from Visual Studio and add the below code in its class file.

C#
using System;

namespace CSharpWithEvent
{
     /// <summary>
    /// Packet that will be used as part of argument in event.
    /// </summary>
    public class UpdateInfo
    {
        public string PropertyName { get; set; }
        public int NewValue { get; set; }
    }
    /// <summary>
    /// Class derived from EventArgs that is used by our event.
    /// </summary>
    public class ValueChangeEventArgs : EventArgs
    {
        private UpdateInfo _updatePacket;

        public UpdateInfo UpdatePacket
        {
            get { return _updatePacket; }
            set { _updatePacket = value; }
        }
        public ValueChangeEventArgs(UpdateInfo updatePacket)
        {
            _updatePacket = updatePacket;
        }
    }
    /// <summary>
    /// Main class that manages events and objects.
    /// </summary>
    public class ImageManager
    {
        private EventHandler<valuechangeeventargs> _onValueChanged;
        public event EventHandler<valuechangeeventargs> OnValueChanged
        {
            add { _onValueChanged += value; }
            remove { _onValueChanged -= value; }
        }

        /// <summary>
        /// Method that is called to update Image.
        /// <summary>
        public void UpdateImage(UpdateInfo updatePacket)
        {
            /*Raised Event*/
            if (_onValueChanged != null)
            {
                _onValueChanged(this, new ValueChangeEventArgs(updatePacket));
            }
        }
        /// <summary>
        /// A method to raise an event from user code itself.
        /// <summary>
        public void RaiseUpdateEvent()
        {
            UpdateInfo updatePacket = new UpdateInfo();
            UpdateImage(updatePacket);
        }
    }
}

Implementing Client/User Application in Managed C++

This is the C++ project that we need to handle event that will be raised from the above C# project.

  1. Create a new C++/CLI CLR Console Application.
  2. To handle an event in native class, we need to write managed wrapper/helper class that will intercept the event and redirect to native object, so here is the simple helper class written in managed C++.
    C++
    //Helper.h
    
    #include "stdafx.h"
    #include <vcclr.h>
    #include "ImageUserClass.h"
    using namespace System;
    
    ref class Helper
    {
    public:
    	Helper();
        ImageUserClass* mPtr;
        void OnImageValueChange( Object^ sender, ValueChangeEventArgs^ updatePacket );
    };
    
    //Helper.cpp
    
    #include "stdafx.h";
    #include "Helper.h"
    #include "ImageUserClass.h"
    
    Helper::Helper()
    {
    	
    }
    void Helper::OnImageValueChange( Object^ sender, ValueChangeEventArgs^ updatePacket )
    {
        mPtr->OnImageValueChange( sender, updatePacket );
    }
  3. At last, we only need a native C++ class which implements event handler. Below is the code for the same.
    C++
    //ImageUserClass.h
    #pragma once
    #include "stdafx.h"
    #include <vcclr.h>
    using namespace std;
    using namespace System;
    using namespace CSharpWithEvent;
    
    class ImageUserClass
    {
    public:
    	gcroot<imagemanager^> m_imageManager;
    	ImageUserClass();
    	void OnImageValueChange(Object^ sender, ValueChangeEventArgs^ updatePacket);
    };
    
    //ImageUserClass.cpp
    
    #include "stdafx.h";
    #include "Helper.h";
    using namespace std;
    using namespace System;
    ImageUserClass::ImageUserClass()
    {
    	Helper^ h = gcnew Helper;
    	h->mPtr = this;
    	m_imageManager = gcnew ImageManager();
    	m_imageManager->OnValueChanged += gcnew EventHandler<valuechangeeventargs^>
                                                 (h, &Helper::OnImageValueChange );
    	<valuechangeeventargs^>m_imageManager->RaiseUpdateEvent();
    }
    void ImageUserClass::OnImageValueChange(Object^ sender, ValueChangeEventArgs^ updatePacket)
    {
    	Console::WriteLine("Update packet received.");
    }

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)