Marshalling C# from DLL to WPF form

197 Views Asked by At

It is possible to "Marshalling" from DLL to WPF Form? For example I like to update Listbox. Which will be the better way to do it?

Before (when I have everthing in one app) I have so defined:

MyMarshalDataToForm(FormActions.AddItemToListBox, "Handle obtained to my device:");

Where,

private enum FormActions
{
    AddItemToListBox,
    DisableInputReportBufferSize,
    EnableGetInputReportInterruptTransfer,
    EnableInputReportBufferSize,
    EnableSendOutputReportInterrupt,
    ScrollToBottomOfListBox,
    SetInputReportBufferSize
}

Where,

private void MyMarshalDataToForm(FormActions action, String textToDisplay)
{
    try
    {
        object[] args = { action, textToDisplay };

        //  The AccessForm routine contains the code that accesses the form.

        MarshalDataToForm marshalDataToFormDelegate = AccessForm;

        //  Execute AccessForm, passing the parameters in args.

        Dispatcher.Invoke(marshalDataToFormDelegate, args);
    }
    catch (Exception ex)
    {
        DisplayException(Name, ex);
        throw;
    }
}

Sorry for so few information in my first post. Now I want to leave Mashal data in .dll and update (for example) ListBox in Main Form. How to do it?

1

There are 1 best solutions below

0
On

Lacking a good, minimal, complete code example that clearly illustrates your scenario, it's not possible to know what the best approach would be.

However, a common approach for separating concerns between main program and DLL like this would be for the DLL to declare an event that the main program can subscribe to.

For example, in the DLL:

public delegate void FormActionHandler(FormActions action, string textToDisplay);

public event FormActionHandler FormAction;

private void MyMarshalDataToForm(FormActions action, String textToDisplay)
{
    try
    {
        object[] args = { action, textToDisplay };

        //  The AccessForm routine contains the code that accesses the form.

        MarshalDataToForm marshalDataToFormDelegate = FormAction;

        //  Execute AccessForm, passing the parameters in args.

        if (marshalDataToFormDelegate != null)
        {
            Dispatcher.Invoke(marshalDataToFormDelegate, args);
        }
    }
    catch (Exception ex)
    {
        DisplayException(Name, ex);
        throw;
    }
}

Then in your main program where, presumable, the AccessForm() method is declared, you would have some code like this:

myDllObject.FormAction += AccessForm;

In this way, when the DLL needs to call the AccessForm() method, it need not actually know about the method per se. Instead, it uses the delegate already created by the main program to call that method, which has been subscribed to the FormAction event.


Note that the above uses a non-standard event signature. This is perfectly legal, but if you want to follow the .NET standard EventHandler<T>-based convention, you can do that too. It involves more code, but has the advantage of being a more-readily-recognizable event pattern.

For example:

class FormActionEventArgs : EventArgs
{
    public FormActions Action { get; private set; }
    public string TextToDisplay { get; private set; }

    public FormActionEventArgs(FormActions action, string textToDisplay)
    {
        Action = action;
        TextToDisplay = textToDisplay;
    }
}

public event EventHandler<FormActionEventArgs> FormAction;

private void MyMarshalDataToForm(FormActions action, String textToDisplay)
{
    try
    {
        FormActionEventArgs args = new FormActionEventArgs(action, textToDisplay);

        //  The AccessForm routine contains the code that accesses the form.

        EventHandler<FormActionEventArgs> marshalDataToFormDelegate = FormAction;

        //  Execute AccessForm, passing the parameters in args.

        if (marshalDataToFormDelegate != null)
        {
            Dispatcher.Invoke(marshalDataToFormDelegate, this, args);
        }
    }
    catch (Exception ex)
    {
        DisplayException(Name, ex);
        throw;
    }
}

Then your main program would subscribe like this:

myDllObject.FormAction += (sender, e) =>
{
    AccessForm(e.Action, e.TextToDisplay);
};