Handling events for an Inherited Form - winforms

I have a base Windows Form with a control. I have declared the control to be protected so his siblings will be able to handle properties, methods and events. This form is written in c#.
One of my clients is using VB.NET, and they have created a new inherited form in their project. Everything works fine ...
But, When they want to handle the control's clicked event in vb.net they're getting this error message:
"Handles clause requires a WithEvents variable defined in the containing type or one of its base types".
Can anybody tell me what should i do on the c# form to let the inherited form in vb.net use the control events?
Thanks for your help!

Two options:
Write some VB which declares a protected WithEvents variable, then decompile it to see what the VB compiler does. (I believe that it makes it a property for one thing, and probably adds a bunch of other bits and pieces.)
Tell them not to use a Handles clause - get them to subscribe explicitly in the same way that you would from C#, using AddHandler and AddressOf.

Related

Visual Studio breaks Visual Inheritance

I have made a FormBase, from which I inherit a FomBaseList and a FormBaseDetail.
All other forms in the project are derived from FormBaseList or FormBaseDetail.
Now it seems that VS has huge problems with that, and my biggest problem is that VS keeps writing property values from the Ancestor form into the designer.cs from the child form.
for example, in FormBaseList I have this property/value :
this.gttDXGridView1.OptionsView.ShowAutoFilterRow = true;
I expect that in a derived form, for example FormClientList, there is no mention for this value in the designer.cs, because it should fetch the value from its parent. In other words, just plain simple basic OOP.
And I also expect that when I change the property in FormClientList to
this.gttDXGridView1.OptionsView.ShowAutoFilterRow = false;
that this is seen as an override from the baseclass.
However, VS keeps overwriting the property in FormClientList.Designer.cs with the value found in FormBaseList.Designer.cs.
This breaks the rules of OOP in my opinion, other tools that support Visual Inheritance like Delphi for example do this correct.
How can I stop VS from doing this ?
The properties are changed using the designer.
All controls are DevExpress controls, or derived from a DevExpress control.
Another example, which works just opposite so its very strange.
For example put a Button on the BaseForm and give it an image.
The button with the image appears on all derived forms.
Now change the image on the button of the BaseForm.
You would expect the image to change on all derived forms also, but that does not happen.
I discovered that again VS has written the property value of the button in all derived designer.cs files, and this time it does not overwrites them.
I created a ticket about this at the DevExpress forum, and they where able to reproduce it.
It is now passed on to their developers.
https://www.devexpress.com/Support/Center/Question/Details/T692940/devexpress-controls-break-visual-inheritance-in-visual-studio
It also seems I was not the first to report a similar problem.
https://www.devexpress.com/Support/Center/Question/Details/T692244/imageoptions-are-serialized-in-a-successor-when-visual-inheritance-is-in-effect

A combination of winforms' controls as a prefab?

In our winforms application we often have a situation where the same panel is used in different forms. Right now I simply copy the code and the designer elements from form to form but that is obviously a terrible practice.
So I thought of making a class that could be easily added to a different form as a "component". The only problem is to be able to prototype and maintain this panel in the visual designer in such a way that if I want to change the panel's appearance in the future it gets changed for every class instance I created.
For instance I have a panel that provides search functionality:
Alongside with the code for click/textChanged events. I want to encapsulate it in a class, which I would be able to instantiate and initialize in any form's constructor to instantly add these controls (alongside events) into that form. Now it is not necessary for me to see the controls in the designer of the recepient form, however, I need to be able to see them in the designer somewhere in order to modify them if I would ever require that.
And if I do modify the appearance somehow (for instance add an extra button) these controls instantly change across the entire project, everywhere I instantiated the class.
I do know that all this can easily be done just creating a new form and encapsulating everything in it, I just wonder if it can be done for a group of controls instead.
You just described the perfect use of a User Control. It's easy to use and direct.
First Add a user COntrol to the project:
Then add the desired controls on the user control:
Build the project and you will see the UserControl on the toolbox:
Add them to the form as a standard control:
If you change the code for the user control (in this case adding a button click handler) uit will affect all the intances of that user control:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text = "Button Clicked"
End Sub
Note: If you have the Control in another project on the same solution, make sure you build that project too if you make any change.

Passing Parameters from one view model to another in wpf

As I continue to adapt to the new world of wpf and mvvm I find myself with another problem which is proving to be a little vexing.
In windows forms if I needed a new form to take a parameter I simply passed the information that I needed to that form's constructor. As Winforms is essentially a code behind model anyway this wasn't an issue.
I now find myself with a MainWindow (controlled by MainWindowViewModel) and a Login (controlled by LoginViewModel) which is shown as a dialog first. I have sorted the issue of the missing dialog result and I can get the main window to show after closing the login dialog.
The login dialog is shown and responded to in the Application startup with the following code;
dim dlg As New Login
If dlg.ShowDialog() = True Then
Else
Current.Shutdown(0)
End If
and I use the use the following in the code behind of the login window to take care of showing the main window when the login dialog closes;
Public Sub New
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Application.Current.ShutdownMode =ShutdownMode.OnExplicitShutdown
End Sub
Protected Overrides Sub OnClosed(e As EventArgs)
MyBase.OnClosed(e)
Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose
End Sub
Now the Mainwindow already knows that it's datacontext is MainWindoViewModel because I set that up when designing it with blend, so how do I pass any parameters that I want to pass from the LoginViewModel to the MainWindowViewModel?
I can read c# but would prefer vb if possible. I know that this is something that I will want to be doing often so if there is a generic way to do this then that's the way I'd like to go.
Thanks
Mvvm frameworks generally implement some kind of messaging system to allow data to be moved between viewmodels or sometimes between viewmodel and view.
You can look at the way messaging is handled in some of the more popular frameworks such as MvvmLight or MvvmCross. It's usually just like an event that uses a weak reference to prevent tight coupling, so you can register for a type of message and then from another viewmodel you publish a message to any registered listeners.
So you will either need to implement your own kind of messenger, or now might be a time to look at starting to use a third party framework, unless you have specific reasons for avoiding this.

Does calling a ScriptableMember method on a Silverlight control from JavaScript create a new Instance of the control?

I have a Silverlight control with a method named DoSomething() decorated with the <ScriptableMember()> attribute. I then call this method successfully from JavaScript and proved by a little message box that apprears from the SL side that says "Method Called!".
Point is all that works. The problem I am having is that prior to calling this method I build up an ObservableCollection on the Silverlight control containing 1..n FileInfo objects. This works fine too and builds up as I add files to it. Each time I add a file, a messagebox tells me the count from Silverlight (i.e. "Count = 2").
Now the problem: when I call the method DoSomething() from JS and access that ObservableCollection the count = 0! To see what is going on I placed a message in the Silverlight control's constructor to see if it gets entered upon being called from JS, and indeed it does and appears to recreate the control.
If this is the case it kind of makes sense that my ObservableCollection has a count = 0 because it is not the same control instance where I built up the FileInfo collection.
So how in the world do I preserve the collection, and why would simply calling a method exposed to JS from Silverlight, recreate the control and not allow me to access it's given state? I don't want a new control, I need to manipulate it as-is. Or am I off base and doing something else wrong to cause this beahvior?
Thoughts? Thanks!
It turns out the instance registered was the culprit. The MSDN examples show registering a new instance of the type, but in my case I needed the actual instance of the Page Control itself which solved the problem.
So at the completion of my page's initialization, I could register the current page's instance like below:
HtmlPage.RegisterScriptableObject("SLControl", Me)
This allowed me from JS to access the control in it's current state which included all objects in the ObservableCollection as required. I blogged about this topic with code examples and the article below expands on this situation:
Get A Silverlight Control's Current Instance For Communicating Via The HTML Bridge:
http://allen-conway-dotnet.blogspot.com/2012/03/get-silverlight-controls-current.html

How to use default CommandButtonsVisibility with Dataform, WCF RIA and POCO Entites?

I have a Silverlight project (in VB), which uses a (WCF RIA) Domain Service, which uses POCO Entities. I'm displaying the data with a DataForm. My Domain Service has InsertUser, UpdateUser, DeleteUser-methods (correctly) specified. CommandButtonsVisibility is not set (so I guess it has default values).
However, the Commit-Button is not visible (it's not only disabled, it's not even there). When I set CommandButtonsVisibility=All I can use the edit button and it is working (changes are saved in db). I would like to use the default behavior though.
I recognized the DataForm automatically shows or hides the buttons if the CRUD-methods are written or not written in the Domain Service (I tested it with my Delete-methods).
What am I doing wrong, are my Update-methods not defined correctly? This is how they look like:
Public Sub UpdateUser(ByVal user As User)
'... update the user
End Sub
For the C#-users:
public void UpdateUser(User user)
//... update the user
End Sub
First thing is first. The DataForm is the buggiest piece of code I've ever encountered in my life. It was mainly designed to be used as a Child view to a DataGrid, in a Master/Child type of a view. And I guess they only tested it with the unmaintainable drap & drop code that's generate, which you see a lot in the intro videos.
Let's get to your problem now:
The most common reason for this is that you're not binding your DataForm to the correct backing data store. If you're binding to a single item, then you're pretty much out of luck. Just implement your own OK and Cancel buttons. But if you're working against a collection, than make sure it implements ICollectionView. (You may get lucky with ObservableCollection as well.)
If you need more specific help, please post the relevant parts of your XAML and code behind.

Resources