How can you add a menu in a main form from a dll? - vb.net

I have a main form that reference to a dll. Inside the dll is also a form that will add additional menu in the main form that calls it. How can I do that? Please show sample codes. thanks.

It is unclear the interaction between those forms but I think you have to pass a main form reference to the other form allowing it to modify main form controls.
Something like this:
MainForm:
Form2 form2=new Form2(this);
Form2:
private MainForm mainForm;
public Form2(MainForm mainForm)
{
this.mainForm=mainForm;
}
private void DoSomething()
{
this.mainForm.Controls. ....
}
updated
You can also use reflection or dynamic type.
look here:
http://www.codeproject.com/KB/cs/csharpreflection.aspx
or here for use of dynamic:
http://msdn.microsoft.com/en-us/library/dd264736.aspx
those example are in c# but it is easy to convert in vb.net with a tool like this:
http://converter.telerik.com/

Related

Excel Add-In: How to show a windows form as MdiChild of Excel Application

I have a windows form [myForm] within a VSTO addin project - currently when I .Show() this form it is displayed outside the Excel application (on another monitor in my case), but I would like it to be displayed as an MdiChild of the Excel application hosting it, so within the main Excel application window.
myForm x = new myForm;
x.Show();
There is an overload of Show() that accepts an owner argument of type System.Windows.Forms.IWin32Window, but I'm not sure if that is how one might do this?
There is also an MdiParent property of the form, which is of type System.Windows.Forms.Form type, but in this case I want the parent to be the Excel application, not another windows form.
The Hwnd property of the Window class returns an integer which stands for the window handle. But the Show method accepts an instance of the IWin32Window interface which exposes Win32 HWND handles. To get an instance of the interface you need to declare a class which implements that interface.
public class WindowImplementation : System.Windows.Forms.IWin32Window
{
public WindowImplementation(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get
{
return _hwnd;
}
}
private IntPtr _hwnd;
}
Then you can use the following code to get form shown specifying the parent Excel window handle.
form1.Show(new WindowImplementation(excelWindow.Hwnd));

Why can my VB.NET User Control not instantiate an ObjectContext?

I have the following lines of code as a test user control. When the project is built, and I drag this user control onto a form, I get an error dialogue to the effect that EF can't find the connection string for the context. Yet when I use the same variable in a form, all is well. It seems the user control is using a different context within which to look for the connection string than the usual app.config.
Public Class InvoiceWorkOrderSearch
Private _dataHelper As WorkOrderData = New WorkOrderData()
End Class
During Design time?
You can avoid this be only instancing the object if the control is in runtime mode.
The build in property to check for desing time (Me.DesignMode) is poor since it only tells you if you are currently designing the control itself. It returs false if you drop the usercontrol on a form.
You can use this code to check for designtime: http://dotnet-snippets.de/dns/designmode-workaround-windows-forms-SID299.aspx
Public Class InvoiceWorkOrderSearch
Private _dataHelper As WorkOrderData
Public Sub New()
If IsDesignMode(me) = False Then
_dataHelper = New WorkOrderData()
End If
End Sub()
End Class

Listbox.SelectedItems.Add not causing SelectionChanged event

I have a custom user control extending the Listbox class. Inside of it I am overriding OnSelectionChanged to add/remove Adorners to any selected/unselected items. This all works when I select an item using the mouse, but when I programmatically add items to the listbox using
myListBox.SelectedItems.Add(newItem) // newItem is already a member of myListBox.Items
It does not execute the OnSelectionChanged code.
Update: Unless I'm crazy (which is always possible) it seems there is a difference in behaviour between calling this from the parent object
myListBox.SelectedItems.Add(newItem)
and this method inside my extended listbox class
Public Sub AddSelectedItem(newItem as Object)
Me.SelectedItems.Add(newItem)
End Sub
For some reason the second option is triggering the event while the first one isn't.
you need to add this line of code first
myListBox.Items.Add(newItem)
The solution here is that calling SelectedItems.Add() from inside an extension of ListBox
public class MyListBox : ListBox
{
public void AddSelectedItems(object newSelectedItem)
{
// works
this.SelectedItems.Add(newSelectedItem);
}
}
will trigger the OnSelectionChanged event.
Calling it like this from the window will not trigger the event
private sub SomeWindowMethod()
{
// does not work
this.MyListBoxInstance.SelectedItems.Add(newSelectedItem);
}

EventAggregation quick start?

I am created a MainView that it's DataContext is a MainViewModel initialized in xaml.
The MainView contains a ContentControl that is bound to the Content property of the MainViewModel.
I added some content in the MainViewModel constructor, so that if the current user is not logged in, it automatucally loads LoginView (and correspondingly it's DataContext LoginViewModel) into this Content property.
Now my question is, what should I do when the user successfully logs in:
'To be called from the LoginCommand
Private Sub Login
'Do Login
If WebContext.Current.User.IsAuthenticated Then
' - Publish a global event to be subscribed and caught from the MainViewModel
' - Close LoginView
' - The MainViewModel should set it's Content property back
' to what the user initially intended to open
End If
End Sub
How is this done?
Note: I prefer using prism's EventAggregator rathen then other stuff, but I have no clue:
How to spread it out between the ViewModels
How to create events (I don't need to pass parameter, nor do I need it to be generic, just Action, LoginAction - no parameters.
How do I subscribe from the MainViewMode.
I do NOT use MEF or Unity, nor do I use seperated modules, all my application is in one single assembly.
I prefer not to write any code in the code-behind at all
Answer in both VB.NET or C# are welcommed the same
Any help would be recommended
You can go here for info regarding the EventAggregator.
You could also use the following code to create an instance of the EventAggregator without using MEF or Unity:
internal static class EventAggregatorHelper
{
private static IEventAggregator _Current = new EventAggregator();
public static IEventAggregator Current
{
get
{
return _Current;
}
}
}
And you could then call the EventAggregator like so passing in the required information to the aggregator:
EventAggregatorHelper.Current.GetEvent<SelectedItemChangedEvent>().
Subscribe(HandleSelectedItemChangedEvent);
In this case the SelectedItemChangedEvent and the subscriber that deals with this event.
The SelectedItemChangedEvent is a class declared as shown below:
public class SelectedItemChangedEvent : CompositePresentationEvent<String>
{
}
and the subscriber would be something like this:
internal void HandleSelectedItemChangedEvent(string viewName)
{
if (!String.IsNullOrEmpty(viewName))
{
//Do whatever you need to do here.
}
}
The link to the Event Aggregator I posted at the start should clear most things up for you.
Hope this helps.

VB.Net thread issue

I am trying to use a DLL that has a public class called FileCleanUp
Inside this class is a procedure called ProcessFiles as shown
public void ProcessFiles(string fileName)
{
this.ProcessFiles(fileName, new ProgressChangedEventHandler(this.ProgressChangedHandler), new RunWorkerCompletedEventHandler(this.WorkCompleteHandler));
}
In VB.Net how do I access the ProcessFiles events so I can inform the user on progress etc from my VB.net application that calls this DLL.
By using Reflector have found that the DLL uses the Background Worker if this is of help.
If this is possible to do - please could you show me a code example \ brief solution.
Thanks for any help.
For your code snippet, ProcessFiles is looks like all you need to do is add a reference to this DLL, create a new instance of FileCleanUp and call ProcessFiles(string)
you may have to pass in ProgressChangedHandler and 'WorkCompleteHandler' (class property or constructor) but it's evident from your snippet.
Dim fileCleanUp as New FileCleanUp()
...
...
fileCleanUp.ProcessFiles(someString)