Callback Eventhandler C# to VB conversion - c#

to create functionallity in my project I need to convert this C# sample to vb.net
I can only connect (Read/Write) to the backend using this API.
to get the details of a customer from a database:
Customer.BeginFetch(CustomerId, AfterFetchingCustomer);
private void AfterFetchingCustomer(object sender, DataPortalResult<Customer> dataPortalResult)
{
Invoke((Action)(() =>
{
_customer = dataPortalResult.Object;
txtShortName.Text = _customer.ShortName;
}));
}
//This is from the API in C#
public static void BeginFetch(string customerId, EventHandler<DataPortalResult<Customer>> callback, AdministrationContext context = null);
I tried:
Dim Debb Debiteur.CustomerId = "DE16000"
Customer.BeginFetch(Debiteur, AfterFetchingCustomer)
End Sub
Private Sub AfterFetchingCustomer(sender As Object, e As DataPortalResult(Of Customer))
End Sub
''This is from the API in VB:
Public Shared Sub BeginFetch(customerId As String, callback As EventHandler(Of DataPortalResult(Of Customer)), Optional context As AdministrationContext = Nothing)
But still get the errors:
Argument not specified for parameter sender ...
Argument not specified for parameter e ...
How can i get this code validated?
So I can continue to work on this program.
Thanks in advance!

Related

call c# from vb.net is hanging

ina c# project i have a static async task written to send emails via tmpt-relay.
the main function is calling this task.
This is working fine.
My Problem is i'm calling this function from a vb.net project, this is also working, email was send but vb.net is hanging in the c#-call
My Code in c#
public class SmoffMail
{
public static string sRet;
public string sendMail(string mailto)
{
RunAsync(mailto).Wait();
return sRet;
}
static async Task RunAsync(string mailto){
MailjetClient client = new MailjetClient("419cce0b9807d1016642156966fc4ec1",
....
sRet = "ok.....";
}
}
From the vb.net i call it like this:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim smail As New smoff.Mailjet.SmoffMail
Dim i As Integer = 0
Dim sRet As String = ""
sRet = smail.sendMail("xxxxxxxh#bluewin.ch")
MsgBox(sRet)
End Sub
End Class
So the function smail.sendMail() was called but is hanging, the next line in code ( msgbox ) is nerver attempt.
Thanks for your help
Your C# should look like this:
public class SmoffMail
{
static async Task<string> SendMailAsync(string mailto){
MailjetClient client = new MailjetClient("419cce0b9807d1016642156966fc4ec1",
....
return "ok.....";
}
}
And your VB should look like this:
Public Class Form1
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sRet As String = ""
sRet = Await smoff.Mailjet.SmoffMail.SendMailAsync("xxxxxxxh#bluewin.ch")
MsgBox(sRet)
End Sub
End Class
Let your VB go back to drawing the UI while it waits for your 2 gigabyte attachment to upload, otherwise there's no point in having any of this be async
i found the solution, the problem was not my code, it was the API Mailjet.client.
after changing the call to this API it works fine

pass an array of strings from c# to Excel VBA

My situation: I'm creating a library using C# that will be called from Excel using VBA code. There's a C# method "SubscribeCallBack" which will receive an address of a VBA Procedure (Function Pointer) and marshal the function pointer into a C# delegate. Let me explain more:
In the C# library there's a variable to store a typed delegate:
public delegate bool TDelegate([MarshalAs(UnmanagedType.BStr)]string str);
TDelegate CallBack = null;
This delegate will run upon some event:
someObj.SomeEvent += (object sender, EventArgs args) => {
if (CallBack != null)
CallBack(someString);
};
And a method exposed to VBA code to set the CallBack:
public void SetCallBack(int callBackAddress) {
try {
CallBack = (TDelegate)Marshal.GetDelegateForFunctionPointer(
new IntPtr(address), typeof(TDelegate));
}
}
Now after the compiled C# library is loaded as a Excel AddIn, I can call C# methods using Application.Run(). I can write this:
Application.Run("SetCallBack", AddressOf VBACallBack)
Public Function VBACallBack(ByVal str As String) As Boolean
Cells(1, 1).Value = str
MsgBox "VBACallBack Running"
VBACallBack = True
End Function
Now things work as expected: I can see VBACallBack got executed when it should be.
Now finally comes the question: I put [MarshalAs(UnmanagedType.Bstr)]string as C# delegate parameter so that the VBA Function with a single string argument can be Marshaled to this typed delegate. Now I need to pass a Function from VBA like this into a C# delegate:
Function(stringArray() As String) As Boolean
taking a String array (or any other thing containing an ordered list of String to make it work)
How exactly can I do this? I tried with [MarshalAs(UnmanagedType.AsAny)]string[] and [MarshalAs(UnmanagedType.LPArray)]string[] both are not working.

Entity Framework 6 second level cache, convert code to vb.net

When i am performing large imports from data to put into sql using entity framework, my code has to check the same foreign keys that results in repetitive commands to the sql server. I believe i need to use 2nd level cache, i have tried to use the efcache from nuget, but as i am only used to vb.net, i am having trouble converting the following c# code:
public class Configuration : DbConfiguration
{
public Configuration()
{
var transactionHandler = new CacheTransactionHandler(new InMemoryCache());
AddInterceptor(transactionHandler);
Loaded +=
(sender, args) => args.ReplaceService<DbProviderServices>(
(s, _) => new CachingProviderServices(s, transactionHandler,
new DefaultCachingPolicy()));
}
}
to vb
Imports System.Data.Entity
Imports EFCache
Public Class Configuration
Inherits DbConfiguration
Public Sub New()
Dim transactionHandler = New CacheTransactionHandler(New InMemoryCache())
AddInterceptor(transactionHandler)
AddHandler Loaded, Function(sender, args) args.ReplaceService(Of
DbProviderServices)(Function(s, _) New CachingProviderServices(s,
transactionHandler, New DefaultCachingPolicy()))
End Sub
End Class
I understand that i need to change c# += to addhandler, but it doesnt recognise dbproviderservices, the underscore _ and DefaultCachingPolicy.
You are using incorrect method signatures.
DbConfiguration.Loaded
Public Shared Event Loaded As EventHandler(Of DbConfigurationLoadedEventArgs)
DbConfigurationLoadedEventArgs.ReplaceService(Of TService)
Public Sub ReplaceService(Of TService) (serviceInterceptor As Func(Of TService, Object, TService))
So the code should look more like this:
AddHandler Loaded,
Sub(sender As Object, e As DbConfigurationLoadedEventArgs)
e.ReplaceService(Of DbProviderServices)(
Function(serviceInterceptor As DbProviderServices, o As Object)
Return New CachingProviderServices(serviceInterceptor, transactionHandler, New DefaultCachingPolicy())
End Function)
End Sub
Compact version:
AddHandler Loaded, Sub(sender As Object, e As DbConfigurationLoadedEventArgs) e.ReplaceService(Of DbProviderServices)(Function(serviceInterceptor As DbProviderServices, o As Object) New CachingProviderServices(serviceInterceptor, transactionHandler, New DefaultCachingPolicy()))

Mediator Helper class in Vb.net [duplicate]

This question already has answers here:
VB.NET equivalent to C# var keyword [duplicate]
(4 answers)
Closed 8 years ago.
I'm looking at trying to implement a mediator helper class to facilitate the transfer of information between viewmodels.
Starting with the following in c#
static public class Mediator
{
static IDictionary<string, List<Action<object>>> pl_dict = new Dictionary<string, List<Action<object>>>();
static public void Register(string token, Action<object> callback)
{
if (!pl_dict.ContainsKey(token))
{
var list = new List<Action<object>>();
list.Add(callback);
pl_dict.Add(token, list);
}
else
{
bool found = false;
foreach (var item in pl_dict[token])
if (item.Method.ToString() == callback.Method.ToString())
found = true;
if (!found)
pl_dict[token].Add(callback);
}
}
static public void Unregister(string token, Action<object> callback)
{
if (pl_dict.ContainsKey(token))
pl_dict[token].Remove(callback);
}
static public void NotifyColleagues(string token, object args)
{
if (pl_dict.ContainsKey(token))
foreach (var callback in pl_dict[token])
callback(args);
}
}
I end up with the following in vb (courtesy of telerik's online converter
Public NotInheritable Class Mediator
Private Sub New()
End Sub
Shared pl_dict As IDictionary(Of String, List(Of Action(Of Object))) = New Dictionary(Of String, List(Of Action(Of Object)))()
Public Shared Sub Register(token As String, callback As Action(Of Object))
If Not pl_dict.ContainsKey(token) Then
Dim list = New List(Of Action(Of Object))()
list.Add(callback)
pl_dict.Add(token, list)
Else
Dim found As Boolean = False
For Each item As var In pl_dict(token)
If item.Method.ToString() = callback.Method.ToString() Then
found = True
End If
Next
If Not found Then
pl_dict(token).Add(callback)
End If
End If
End Sub
Public Shared Sub Unregister(token As String, callback As Action(Of Object))
If pl_dict.ContainsKey(token) Then
pl_dict(token).Remove(callback)
End If
End Sub
Public Shared Sub NotifyColleagues(token As String, args As Object)
If pl_dict.ContainsKey(token) Then
For Each callback As var In pl_dict(token)
callback(args)
Next
End If
End Sub
End Class
The compiler doesn't like the two For Each <...> As var statements. I'm assuming that this is linq c# style which has always been very difficult to translate with ease. This one has me ostensibly because I'm still trying to fathom out the whole principle anyway. Can anyone suggest a proper construct for the two lines in question.
Thanks
In VB, the equivalent of var is to simply declare the variable without specifying the type, for instance:
For Each callback In pl_dict(token)
callback(args)
Next
However, in order for that to work, you need to have Option Infer On. Alternatively, you could just specify the type of the iterator variable as whatever it actually is (in this case, Action(Of Object)), like this:
For Each callback As Action(Of Object) In pl_dict(token)
callback(args)
Next

C# > VB Conversion, RelayCommand behaves differently

[Visual C#]
public ICommand MyCommand
{
get
{
if (this.myCommand == null)
{
this.myCommand = new RelayCommand(this.ShowMyCommand);
}
return this.myCommand;
}
}
private void ShowMyCommand(object param)
{
...
}
This code works fine, but when I convert it to Visual Basic:
[Visual Basic]
Private _myCommand As RelayCommand
Public ReadOnly Property MyCommand As ICommand
Get
If Me._myCommand Is Nothing Then
Me._myCommand = New RelayCommand(Me.ShowMyCommand)
End If
Return Me._myCommand
End Get
End Property
Private Sub ShowMyCommand(ByVal param As Object)
...
End Sub
I get the error:
Error 3 Argument not specified for
parameter 'param' of 'Private Sub
ShowMyCommand(param As Object)'.
Any ideas? I am just doing blind conversion so I don't understand what the project does, I am just converting it.
I am a bit on thin ice when it comes to VB, but according to what I know, you need to prefix the method name with the keyword AddressOf in order for it to be usable as a method group for the event.
The following line:
Me._myCommand = New RelayCommand(Me.ShowMyCommand)
Needs to be written as:
Me._myCommand = New RelayCommand(AddressOf Me.ShowMyCommand)
The error message is because the compiler is trying to compile a call to the method, and is thus missing the argument to its parameter.

Categories