![]() | |
![]() |
| | Thread Tools | Search this Thread | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
We've created a COM component in C# which needs to be able to raise events to a managed code consumer of the COM component (Silverlight 4 in this case). We can call methods on the COM component just fine but when we try to register the event handler it throws and gives an error indicating it can't find the event we're specifying. As an asside, it would be GREAT to be able to test this outside of SL with a console app or unit test, but when we try to reference the managed COM component from a non-Silverlight managed client, the IDE barks and tells us to just add a reference to the assembly [instead of using COM]. Here's the code we're using to defne the event on the COM component side: namespace DeviceCom { * * public delegate void DeviceEventHandler(object sender, * * DeviceEventArgs e); * * public class DeviceEventArgs : EventArgs * * { * * * * public string Data { get; set; } * * * * public DeviceEventArgs() { } * * * * public DeviceEventArgs(string data) * * * * { * * * * * * Data = data; * * * * } * * } } The event Interface looks like this: namespace DeviceCom { * * [Guid("7E1E5F7D-3303-4A15-8025-CB8458AF1949"), * * InterfaceType(ComInterfaceType.InterfaceIsIDispatc h)] * * public interface IDeviceComEvents * * { * * * * event DeviceEventHandler LeftLineDataReceived; * * } } The COM object that raises the event (and implements the above interface): namespace DeviceCom { * * [Guid("38814898-A470-42DE-AD21-9AB29B5A536E"), * * ClassInterface(ClassInterfaceType.None), * * ComSourceInterfaces(typeof(IDeviceComEvents))] * * public class DeviceComManager : DeviceCom.IDeviceComManager * * { * * * * public DeviceComManager() { } * * * * public void InitializeDevices() * * * * { * * * * * * DeviceInformation deviceInfo = new DeviceInformation("Left * * * * * * Line Pin", * * * * * * * * "COM3,9600,N,8,1", * * * * * * * * "/HORIZON", * * * * * * * * false, 1, 1, true, CommunicationStyles.Horizon, * * * * * * * * DeviceManager.CashDrawerType.None); * * * * * * List<DeviceInformation> deviceList = new * * * * * * List<DeviceInformation>(); deviceList.Add(deviceInfo); * * * * * * DeviceManager.InitializeDevices(deviceList); * * * * * * DeviceManager.LeftLineDataReceived +=new * * * * * * DeviceManager.LeftLineDataReceivedEventHandler(Dev iceManager_ * * * * * * LeftLineDataReceived); * * * * } * * * * public string HelloWorld() * * * * { * * * * * * return "Hello World"; * * * * } * * * * private void DeviceManager_LeftLineDataReceived(object sender, * * * * DeviceArgs e) { * * * * * * LeftLineDataReceived(this, new * * * * * * DeviceEventArgs(e.DataReceived)); * * * * } * * * * public event DeviceEventHandler LeftLineDataReceived; * * } } And here's the line that throws when we try to handle the event on the Silverlight side: * * public partial class MainPage : UserControl * * { * * * * public MainPage() * * * * { * * * * * * InitializeComponent(); * * * * } * * * * private void Button_Click(object sender, RoutedEventArgs e) * * * * { * * * * * * Go(); * * * * } * * * * private void Go() * * * * { * * * * * * dynamic device = * * * * * * AutomationFactory.CreateObject("DeviceCom.DeviceCo mManager"); * * * * * * device.InitializeDevices(); * * * * * * AutomationEvent hzDeviceEvent = * * * * * * AutomationFactory.GetEvent(device, "LeftLineDataReceived"); //****>> This next line throws! * * * * * * hzDeviceEvent.EventRaised += (sender, e) = * * * * * * { * * * * * * * * MessageBox.Show((string)e.Arguments[0]); * * * * * * }; * * * * * * string hw = device.HelloWorld(); * * * * * * if (hw != null) * * * * * * { * * * * * * * * MessageBox.Show(hw); * * * * * * } * * * * } * * * * void hzDeviceEvent_EventRaised(object sender, * * * * AutomationEventArgs e) { * * * * * * MessageBox.Show((string)e.Arguments[0]); * * * * } * * } Lastly, here is the exception that the above event registration throws: System.Exception was unhandled by user code * Message=Failed to add event handler. Possible reasons include: the * object does not support this or any events, or something failed while * adding the event. StackTrace: * * * *at MS.Internal.Error.MarshalXresultAsException(UInt32 hr, * * * *COMExceptionBehavior comExceptionBehavior) at * * * *MS.Internal.XcpImports.CheckHResult(UInt32 hr) at * * * *MS.Internal.ComAutomation.ComAutomationNative.Con nectEvent(IntPtr * * * *nativePeer, String eventName, RaiseComAutomationEventDelegate * * * *raiseComAutomationEventDelegate) at * * * *MS.Internal.ComAutomation.ComAutomationObject.Con nectEvent(String * * * *name) at * * * *System.Runtime.InteropServices.Automation.Automat ionEvent.UpdateCo * * * *nnection() at * * * *System.Runtime.InteropServices.Automation.Automat ionEvent.add_Even * * * *tRaised(EventHandler`1 value) at * * * *SilverlightApplication1.MainPage.Go() at * * * *SilverlightApplication1.MainPage.Button_Click(Obj ect sender, * * * *RoutedEventArgs e) at * * * *System.Windows.Controls.Primitives.ButtonBase.OnC lick() at * * * *System.Windows.Controls.Button.OnClick() at * * * *System.Windows.Controls.Primitives.ButtonBase.OnM ouseLeftButtonUp( * * * *MouseButtonEventArgs e) at * * * *System.Windows.Controls.Control.OnMouseLeftButton Up(Control ctrl, * * * *EventArgs e) at MS.Internal.JoltHelper.FireEvent(IntPtr * * * *unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, * * * *String eventName) |
#3
| |||
| |||
|
|
We've created a COM component in C# which needs to be able to raise events to a managed code consumer of the COM component (Silverlight 4 in this case). We can call methods on the COM component just fine but when we try to register the event handler it throws and gives an error indicating it can't find the event we're specifying. As an asside, it would be GREAT to be able to test this outside of SL with a console app or unit test, but when we try to reference the managed COM component from a non-Silverlight managed client, the IDE barks and tells us to just add a reference to the assembly [instead of using COM]. Here's the code we're using to defne the event on the COM component side: namespace DeviceCom { public delegate void DeviceEventHandler(object sender, DeviceEventArgs e); public class DeviceEventArgs : EventArgs { public string Data { get; set; } public DeviceEventArgs() { } public DeviceEventArgs(string data) { Data = data; } } } The event Interface looks like this: namespace DeviceCom { [Guid("7E1E5F7D-3303-4A15-8025-CB8458AF1949"), InterfaceType(ComInterfaceType.InterfaceIsIDispatc h)] public interface IDeviceComEvents { event DeviceEventHandler LeftLineDataReceived; } } The COM object that raises the event (and implements the above interface): namespace DeviceCom { [Guid("38814898-A470-42DE-AD21-9AB29B5A536E"), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IDeviceComEvents))] public class DeviceComManager : DeviceCom.IDeviceComManager { public DeviceComManager() { } public void InitializeDevices() { DeviceInformation deviceInfo = new DeviceInformation("Left Line Pin", "COM3,9600,N,8,1", "/HORIZON", false, 1, 1, true, CommunicationStyles.Horizon, DeviceManager.CashDrawerType.None); List<DeviceInformation> deviceList = new List<DeviceInformation>(); deviceList.Add(deviceInfo); DeviceManager.InitializeDevices(deviceList); DeviceManager.LeftLineDataReceived +=new DeviceManager.LeftLineDataReceivedEventHandler(Dev iceManager_ LeftLineDataReceived); } public string HelloWorld() { return "Hello World"; } private void DeviceManager_LeftLineDataReceived(object sender, DeviceArgs e) { LeftLineDataReceived(this, new DeviceEventArgs(e.DataReceived)); } public event DeviceEventHandler LeftLineDataReceived; } } And here's the line that throws when we try to handle the event on the Silverlight side: public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { Go(); } private void Go() { dynamic device = AutomationFactory.CreateObject("DeviceCom.DeviceCo mManager"); device.InitializeDevices(); AutomationEvent hzDeviceEvent = AutomationFactory.GetEvent(device, "LeftLineDataReceived"); //****>> This next line throws! hzDeviceEvent.EventRaised += (sender, e) = { MessageBox.Show((string)e.Arguments[0]); }; string hw = device.HelloWorld(); if (hw != null) { MessageBox.Show(hw); } } void hzDeviceEvent_EventRaised(object sender, AutomationEventArgs e) { MessageBox.Show((string)e.Arguments[0]); } } Lastly, here is the exception that the above event registration throws: System.Exception was unhandled by user code Message=Failed to add event handler. Possible reasons include: the object does not support this or any events, or something failed while adding the event. StackTrace: at MS.Internal.Error.MarshalXresultAsException(UInt32 hr, COMExceptionBehavior comExceptionBehavior) at MS.Internal.XcpImports.CheckHResult(UInt32 hr) at MS.Internal.ComAutomation.ComAutomationNative.Conn ectEvent(IntPtr nativePeer, String eventName, RaiseComAutomationEventDelegate raiseComAutomationEventDelegate) at MS.Internal.ComAutomation.ComAutomationObject.Conn ectEvent(String name) at System.Runtime.InteropServices.Automation.Automati onEvent.UpdateCo nnection() at System.Runtime.InteropServices.Automation.Automati onEvent.add_Even tRaised(EventHandler`1 value) at SilverlightApplication1.MainPage.Go() at SilverlightApplication1.MainPage.Button_Click(Obje ct sender, RoutedEventArgs e) at System.Windows.Controls.Primitives.ButtonBase.OnCl ick() at System.Windows.Controls.Button.OnClick() at System.Windows.Controls.Primitives.ButtonBase.OnMo useLeftButtonUp( MouseButtonEventArgs e) at System.Windows.Controls.Control.OnMouseLeftButtonU p(Control ctrl, EventArgs e) at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName) |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
| |